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;

    }

};

 

你可能感兴趣的:(LeetCode)