[leetcode]First Missing Positive

    xiaoxiao2021-04-16  36

    First Missing Positive

    Difficulty:Hard

    Given an unsorted integer array, find the first missing positive integer.

    For example, Given [1,2,0] return 3, and [3,4,-1,1] return 2.

    Your algorithm should run in O(n) time and uses constant space.

    题目就是要找出给的未排序数组中,第一个不存在其中的自然数,也就是第一个不存在的正整数。题目要求时间复杂度是O(n),空间复杂度是O(1).

    一开始觉得数组中会有很多连续的数,所以就想对插入排序进行改进来计算,改进就是想在已经插入的数中,如果是连续的就只保存开头和结尾,比如(2,3,4,5就只用2->5来保存),整个插入排序用链表进行维护,这样每次插入要比较的数量就会少很多。

    后来想想这个做法在数组中连续的数很少的情况下根本没什么优势,并不能保证复杂度都是 O(n)和空间复杂度是O(1),不过leetcode还是给通过了,而且比70%已通过的算法都快,不知道是不是直接用插入排序也会给通过。。。

    最后看了网上的解答,通过在原数组的进行交换,把数放到该放的位置上,比如数字5就与数组第5个位置的数进行交换,进行两次循环就能找出答案,我这真的太麻烦了。。。

    int firstMissingPositive(vector<int>& nums) { if (nums.size() == 0)//为空返回1 return 1; list<pair<int, int>> record;//第一个int是插入的数 第二个数表示状态 0表示左右没有连续 1表示是连续数的开头 2表示连续数的结尾 int i = 0; for (; i < nums.size(); i++){//找到第一个大于0的数的位置并把数插入到record中 if (nums[i] > 0){ record.push_back(pair<int, int>(nums[i], false)); break; } } for (i=i + 1; i < nums.size(); i++){//循环生成record list<pair<int, int>>::iterator it = record.begin(); list<pair<int, int>>::iterator it_last; int k = 0; if (nums[i]>0) while (1){ if (it != record.end()){//寻找插入点 头/中间插入 if (nums[i] > it->first){//未寻找到插入点 it_last = it; it++; k++; } else{//寻找到插入点 if (k>0){//中间插入 if (it->first == nums[i] || (it_last->second == 1 && it->second == 2)) break; if ((nums[i] - it_last->first) == 1 && (it->first - nums[i]) == 1){//左右都与插入值相连 if (it_last->second >0 && it->second > 0){//当前是连续输结尾 后是连续输开头时才应该插入 if (it_last->second > it->second){ record.erase(it_last); record.erase(it); } break; } else if (it_last->second >0){ it->second = 2; record.erase(it_last); break; } else if (it->second > 0){ it_last->second = 1; record.erase(it); break; } else{ it_last->second = 1; it->second = 2; break; } } else if ((nums[i] - it_last->first) == 1){ //与左边相连 if (it_last->second >0){ record.insert(it, pair<int, int>(nums[i], 2)); record.erase(it_last); break; } else{ record.insert(it, pair<int, int>(nums[i], 2)); it_last->second = 1; break; } } else if ((it->first - nums[i]) == 1){//与右边相连 if (it->second > 0){ record.insert(it, pair<int, int>(nums[i], 1)); record.erase(it); break; } else{ it->second = 2; record.insert(it, pair<int, int>(nums[i], 1)); break; } } else{//左右都不相连 record.insert(it, pair<int, int>(nums[i], 0)); break; } } else{//头部插入 if (it->first == nums[i]) break; if ((it->first - nums[i]) == 1){ if (it->second == 0){ it->second = 2; record.push_front(pair<int, int>(nums[i], 1)); break; } else{ record.push_front(pair<int, int>(nums[i], 1)); record.erase(it); break; } } else{ record.push_front(pair<int, int>(nums[i], 0)); break; } } } } else{//末尾插入 if ((nums[i] - it_last->first) == 1){ if (it_last->second == 0){ it_last->second = 1; record.push_back(pair<int, int>(nums[i], 2)); break; } else{ record.push_back(pair<int, int>(nums[i], 2)); record.erase(it_last); break; } } else{ record.push_back(pair<int, int>(nums[i], 0)); break; } } } } list<pair<int, int>>::iterator it = record.begin(); list<pair<int, int>>::iterator it_tmp = it; bool isEnd = false; for (int j = 1; j <= nums.size()+1; j++){//查找第一个丢失的正整数 if (j != it->first){ if (j < it->first){ return j; } else{ if (it->second ==1){ it_tmp = it; it_tmp++; if (it_tmp != record.end()){ if (it_tmp->first <= j){ it++; j--; } } else{ return j; } } else if (it->second == 2){ return j; } else{ return j; } } } } return 1; }

    转载请注明原文地址: https://ju.6miu.com/read-673209.html

    最新回复(0)