LeetCode First Missing Positive

class Solution {

public:

    int firstMissingPositive(int A[], int n) {

        if (A == NULL || n < 1) return 1;



        size_t len = (size_t)n + 1;

        vector<bool> bits(len, false);

        for (int i=0; i<n; i++) {

            if (A[i] < 0 || A[i] > n) continue;

            bits[A[i]] = true;

        }

        int miss = 1;

        while (miss <= INT_MAX) {

            if (!bits[miss]) return miss;

            if (miss == INT_MAX) {

                cout<<"no missing positive"<<endl;

                break;

            }

            miss++;

        }

        bits.clear();

        return 0;

    }

    

    int firstMissingPositive2(int A[], int n) {

        if (A == NULL || n < 1) return 1;



        unordered_map<int, int> mark;

        for (int i=0; i<n; i++) {

            mark[A[i]] = 1;

        }



        int miss = 1;

        while (miss <= INT_MAX) {

            if (mark.find(miss) == mark.end()) return miss;

            if (miss == INT_MAX) {

                cout<<"no missing positive"<<endl;

                return 0;

            }

            miss++;

        }

        return miss;

    }

    

    int firstMissingPositive3(int A[], int n) {

        if (A == NULL || n < 1) return 1;



        for (int i = 0; i<n; i++) {

            if (A[i] <= 0) A[i] = n + 1;

        }

        for (int i=0; i<n; i++) {

            int cur = A[i] < 0 ? -A[i] : A[i];

            if (cur <= n) A[cur - 1] = A[cur - 1] < 0 ? A[cur - 1] : -A[cur - 1];

        }

        int miss = 1;

        for (int i=0; i<n; i++) {

            if (A[i] > 0) break;

            miss++;

        }

        return miss;

    }

};

心烦,因为要找出数组A[n]中第一个缺失的整数,如果数组中有元素大于n那么这个数组必定至少缺失了一个数,因为如果A[n]包含[1,n]那么刚刚n个数,一个不少,且每个数小于n,如果某个元素大于n了,则中间肯定有间隙存在,否则元素个数将大于n。利用这一特征我们可以把负数和大于n的数都置为n+1这样在下一次扫描时可以忽略它们。

解法三存在一个问题,当n=INT_MAX且有负数存在时会出错。

 

第二轮:

解法三应该是从disscus上搞过来的,这个跟使用常数空间找一个无序数组(数组元素范围小于长度值)中的重复值类似,可以使用负数作为标记。实际上是使用了每个元素的符号位这样的一系列1bit的存储空间。反正已经将数组破坏掉了,还可以这样写避免数值溢出:

 1 class Solution {

 2 public:

 3     int firstMissingPositive(vector<int>& nums) {

 4         int len = nums.size();

 5         int idx = 0;

 6         for (idx = 0; idx < len; idx++) {

 7             if (nums[idx] == 1) {

 8                 break;

 9             }

10         }

11         if (idx == len) {

12             return 1;

13         }

14         

15         for (int i=0; i<len; i++) {

16             nums[i] = max(1, nums[i]);

17         }

18         

19         for (int i=0; i<len; i++) {

20             idx = abs(nums[i]) - 1;

21             if (idx >= len) {

22                 continue;

23             }

24             if (nums[idx] > 0) {

25                 nums[idx] = -nums[idx];

26             }

27         }

28         idx = 0;

29         while (nums[idx] < 0 && idx < len) idx++;

30         return idx + 1;

31     }

32 };

把小于等于0的数全部置为1,当然首先要检测一下1是否存在。

你可能感兴趣的:(LeetCode)