zoukankan      html  css  js  c++  java
  • 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;
        }
    };
    



    参考




  • 相关阅读:
    路由基础、多app共存,路由分配、路由分发(将app自己的路由分发给应用自身管理)、反解
    Django项目的创建与介绍,三件套,静态文件,配置Mysql完成数据迁移,单表ORM记录的增删改查
    Django框架导读
    Flask简易版本、Ajax、DOM操作,表单操作
    JQuery
    0820-信心赛
    codeforces比赛总(吐)结(嘈)
    洛谷P3403 跳楼机(最短路)
    求逆序对的三种方法
    NKOJ 3751 扫雷游戏
  • 原文地址:https://www.cnblogs.com/Bw98blogs/p/12675687.html
Copyright © 2011-2022 走看看