• 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;
        }
    };
    



    参考




  • 相关阅读:
    AngularJS实现跨域请求
    从古代名著看领导与被领导的艺术
    关于学习视频教程的反思之中的一个
    关于tcp中time_wait状态的4个问题
    AjaxPro因为汉字文件夹引发的IE兼容性问题
    MySQL无法重启问题解决Warning: World-writable config file ‘/etc/my.cnf’ is ignored
    安全运维之:Linux系统账户和登录安全
    mongodb导入导出备份恢复
    mongodb数据库备份恢复
    mongodb
  • 原文地址:https://www.cnblogs.com/Bw98blogs/p/12675687.html
Copyright © 2020-2023  润新知