LeetCode 41 - First Missing Positive(Most Interesting Problem So Far !!!!)

41. First Missing Positive

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

Example 1:

Input: [1,2,0]
Output: 3

Example 2:

Input: [3,4,-1,1]
Output: 2

Example 3:

Input: [7,8,9,11,12]
Output: 1

Note:

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


这题看了hint 1才想到怎么做,很有趣,所以在这里写下题解,分享给大家。


Hint1

Think about how you would solve the problem in non-constant space. Can you apply that logic to the existing space?

这题平常的做法即桶排,因为答案不会超过数组长度n,所以利用一个长度为n的数组标记对应的数字有没有出现过即可。

现在要求砍空间,我们可以利用题目所给的原数组做标记,不需要另外开辟新数组。可是,怎么同时保存原数组呢?同样,因为答案不会超过数组长度n,可以把大小为i的数放在数组的i号位置,这样最后按顺序扫描一遍数组,找到第一个下标和这个下标对应的值不同的位置就是答案。

如何在O(n)时间内完成把大小为i的数放在数组的i号位置?对于i号位置,如果这里的数值小于1或大于n,则肯定不是答案,跳过即可;否则,把它换到正确的位置,对换来的数重复进行上述操作。因为最多有n个数将要被换到正确位置,所以时间复杂度就是O(n)。

在题目中,输入是vector,所以下标对应的数值是下标的值+1,即判断交换停止的条件是nums[i]!=i+1.

有一种特殊情况要注意,如果i号位置的数和换过来的数相等,说明这次交换没有意义,不断交换会陷入死循环。所以,需要判断nums[i]!=nums[nums[i]-1]。

class Solution {
public:
    int firstMissingPositive(vector<int>& nums) {
        int n = nums.size();
        for (int i=0;i<n;i++) {
            while (nums[i]!=i+1 && nums[i]>0 && nums[i]<=n && nums[i]!=nums[nums[i]-1]) {
                swap(nums[i], nums[nums[i]-1]);
            }
        }
        for (int i=0;i<n;i++) {
            if (nums[i]!=i+1) return i+1;
        }
        return n+1;
    }
};

你可能感兴趣的:(XJB猜)