leetcode problem 41 -- First Missing Positive

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.

题意:

  给定了一个无序数组,要求找到第一个缺失的正整数.如1,2,4,5的第一个缺失的正整数是3.要求时间复杂度为o(n) 空间复杂度为o(1)

思路:

  第一种是排序,时间复杂度为O(nlgn) 不行

  第二种是hash查找  对每一个数字都用额外空间找到正确的位置. 然后一次遍历找到第一个缺失的正整数.  时间复杂度为O(n)  但是空间复杂度为O(n) 也不符合题目要求

  第三种直接在输入数组上进行交换操作, 使得每个数字通过交换能在正确的位置上.如3,1,7,2 这组数字第一次交换后得到7,1,3,2   数字3放置在了正确的位置.

    这种时间复杂度为O(n)  而且只需要常数辅助空间.  但我认为这种方法依然不复合题目要求,因为它破坏了原始数组.  它其实也类似于hash, 需要O(n)的空间,只不过这O(n)的空间借用了原始输入数组上的.

  目前我还没找到即不破坏原始数组,空间复杂度又为O(1)的方法

代码1(hash法):

  

class Solution {
public:
    int firstMissingPositive(vector<int>& nums) {
        if (nums.size() == 0)
            return 1;
        auto it_max = std::max_element(nums.begin(), nums.end());    
        auto it_min = std::min_element(nums.begin(), nums.end());

        vector<bool> vec(*it_max - *it_min, false);
        for (auto elem : nums) 
            vec[elem - *it_min] = true;
        for (auto it = 1; it <= *it_max; ++it) {
            if (it < *it_min || (it > 0 && !vec[it - *it_min]))
                return it;
        }    
        return *it_max > 0 ? *it_max + 1 : 1;
    }

private:
};

代码2(直接在原数组上进行交换, 空间代价为o(1))

class Solution {
public:
    int firstMissingPositive(vector<int>& nums) {
        if (nums.empty())
            return 1;
        auto begin = getFirstPositivePos(nums);
        if (*begin < 0)
            return 1;
        for (auto it = begin; it != nums.end(); ) {
            auto realPos = begin + *it - 1;
            if (realPos < nums.end() && realPos != it && *realPos != *it)
                iter_swap(it, realPos);
            else
                ++it;
        }
        int index = 1;
        for (auto it = begin; it != nums.end(); ++it, index++) {
            if (index != *it)
                return index;
        }
        return index;
    }

private:
    vector<int>::iterator getFirstPositivePos(vector<int>& nums) {
        auto first = nums.begin();
        auto last = nums.end()-1;
        while (true) {
            while (first < last && *first <= 0 ) 
                ++first;
            while (first < last && *last > 0)
                --last;
            if (first < last)
                iter_swap(first, last);    
            else
                break;
        }
        return first;
    }
};
原文地址:https://www.cnblogs.com/lysuns/p/4479212.html