LeetCode #41 First Missing Positive 数组

Description


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.



思路


解法一

题目要让我们找出一个数组中缺失的最小正整数。

通过分析发现,对于一个长度为 n 的数组,它缺失的最小正整数只能是 [1, 2, ..., n] 中的一个。
因此,创建一个 HashSet 并存入 nums 中所有元素的值,遍历从 1 到 n ,找到第一个缺失的正整数,就是 nums 中缺失的最小正整数。

时间复杂度:拷贝到set O(n) + 找出缺失的最小正整数 O(n) = O(n)
空间复杂度:开辟一个 nums.size 大小的 set O(n) = O(n)

耗时 8 ms, 占用空间 6.8 MB, ranking 50%

class Solution {
public:
    int firstMissingPositive(const vector<int> &nums) {
        if (nums.empty()) return 1;
        
        unordered_set<int> nums_set(nums.cbegin(), nums.cend());
        
        // for an array, min positive seq is [1, 2, ..., nums.size()]
        // so the missing positive must be one of them
        int i = 1;
        while (i <= nums.size()) {
            if(nums_set.find(i) == nums_set.end()) {
                break;  // find the min missing positive
            } else {
                ++i;
            }
        }
        
        return i;
    }
};



解法二

思路还是和解法一相同,但是需要进一步压缩space。

想要实现 O(1) 时间复杂度的访问与修改,以及 O(1) 的存储空间,还是需要数组的支持,而且只能基于原数组进行增删改查。

因为缺失的正整数一定是 [1, 2, ..., n] 中的一个,所以我们可以遍历 nums,把值在 [1, n] 范围内的移动到数组 [0, n-1] 的位置上,以便用 O(1) 的空间找到缺失的最小正整数。

时间复杂度:移动操作 O(n) + 找出缺失的最小正整数 O(n) = O(n)
空间复杂度:原址修改 O(1)

耗时为 4 ms, 占用空间 6.5 MB, ranking 55%

class Solution {
public:
    int firstMissingPositive(vector<int> &nums) {
        if (nums.empty()) return 1;
        
        // for an array, min positive seq is [1, 2, ..., nums.size()]
        // so the missing positive must be one of them
        for (int i = 0; i < nums.size(); ++i) {
            if (nums[i] > 0 && nums[i] <= nums.size()) {
                if (nums[nums[i] - 1] == nums[i]) {
                    continue;    
                }
                
                swap(nums[nums[i] - 1], nums[i]);
                --i;  // check swaped element in current position
            }
        }
        
        // compare with the min positive seq [1, 2, ..., nums.size()]
        int i = 1;
        while (i <= nums.size()) {
            if (nums[i-1] == i) {
                ++i;
            } else {
                break;  // find the min missing positive
            }
        }
        
        return i;
    }
};



参考




原文地址:https://www.cnblogs.com/Bw98blogs/p/12675687.html