leetcode 41 缺失的第一个正数

41 缺失的第一个正数
给你一个未排序的整数数组,请你找出其中没有出现的最小的正整数。
示例 1:输入: [1,2,0]输出: 3
示例 2:输入: [3,4,-1,1]输出: 2
示例 3:输入: [7,8,9,11,12]输出: 1

提示:你的算法的时间复杂度应为O(n),并且只能使用常数级别的额外空间。

 

思路1:
hash 表, 从小到大枚举检查1 ~ nums.size()是否在数组中存在,如果不存在则说明我们找到了最小的不存在数字。

class Solution {
public:
    int firstMissingPositive(vector<int>& nums) {
        unordered_set<int> nums_set;
        for(int n : nums)   nums_set.insert(n);
        for(int i = 1; i <= nums.size(); i++)
            if(!nums_set.count(i))   return i;
        return nums.size() + 1;
    }
};

  

 

思路2:先排序再找

class Solution {
public:
    int firstMissingPositive(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        int ans = 1;
        for(int num : nums){
            if(num == ans)
                ans++;
        }
        return ans;
    }
};

  

 

思路3:利用原数组哈希
我们考虑使用原数组实现哈希表。我们将映射公式设为nums[i] = i+1。
即下标为0,存放1;下标为1,存放2......假设nums数组长度为n,那么最后的答案应该在[1,n+1]范围内,且只有当nums为存放的为1-n内的所有正整数时,答案才为n+1。
我们遍历nums,判断nums[i],当它的值范围在[1,n]中,就将它与nums[nums[i]-1]进行互换,
此时还需要判断nums[nums[i]-1]是不是与nums[i]已经相等了,这时就是遇到了重复的元素,pass。
遍历完之后,我们再一次遍历更改后的nums数组,当nums[i] != i+1,返回i+1即可,若遍历结束之后没有返回,返回n+1即可。

也就是,第一次遍历将数据归位,
第二次遍历检查,谁缺失了即可

 

class Solution {
public:
    int firstMissingPositive(vector<int>& nums) {
        int n = nums.size();
        for(int i = 0; i < n; i++){
            while(nums[i] >= 1 && 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;
    }
};

  

 

posted @ 2020-11-03 15:04  静悟生慧  阅读(126)  评论(0编辑  收藏  举报