[Leetcode] 41. First Missing Positive

41. First Missing Positive

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

For example,
Given [1,2,0] return 3,
and [3,4,-1,1] return 2.

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

给定一个未排序的整数数组,找到第一个遗失的整数。

例如:
给定[1,2,0]返回3;
给定[3,4,-1,1] 返回2.

算法时间复杂度为O(n),并且使用常数空间。

解题思路

方法一:哈希表

这是一题困难度标记为Hard但是其实很简单的题目。解决这题很自然而然的想到使用哈希表记录出现的数据,然后载扫描一遍数组,找到第一个没出现的整数就可以了。但是哈希表的长度设置是一个问题,因为我们并不知道整数的范围。因此,刚开始的想法是使用两个变量记录整数数组中最大和最小的整数,从而确定哈希表的范围。 但是再继续深入,可以发现其实并不需要这样。因为负数和0不需要考虑,而满足条件的最大整数一定是大于0并且小于n(n为数组的长度)的。因为假设给定的数组都是整数,并且最小的整数是1,那么之后的数字最大只能是n,才能保证中间没有缺失的整数。所以,我们再记录哈希表的时候,不需要考虑负数,0以及小于n的整数。因此,最终的代码如下:

int firstMissingPositive(vector<int>& nums) {
    vector<int> bucket (nums.size(), 0);
    for (int i = 0; i < nums.size(); ++i)
    {
        if (nums[i] > 0 && nums[i] <= nums.size()) {
            bucket[nums[i]-1] = 1;
        }
    }

    for (int i = 0; i < nums.size(); ++i)
    {
        if (bucket[i] == 0) 
            return i + 1;
    }
    return nums.size() + 1;

}

方法二:桶排序

第二种方法就是使用桶排序 。其实这种方法跟哈希表方法是一样的思路,只是将hash[i] = 1/0 ,变成了bucket[i]=i/0。


int firstMissingPositive(vector<int>& nums) {
    vector<int> bucket (nums.size()+1, 0);
    for (int i = 0; i < nums.size(); ++i)
    {
        if (nums[i] > 0 && nums[i] <= nums.size()) {
            bucket[nums[i]] = nums[i];
        }
    }

    for (int i = 1; i <= nums.size(); ++i)
    {
        if (bucket[i] != i) 
            return i;
    }
    return nums.size() + 1;

}

但是目前的方法一和方法二的空间复杂度其实都是0(n),能不能再减小一点呢?可以,直接使用原来的数组作为桶,就不需要额外的空间了。如此,当我们发现nums[i]!=i+1的时候,就表示需要排序。排序的操作就是交换 nums[i] 和 nums[nums[i]-1]。因此,最终的代码变为:

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

如此,算法的时间复杂度为O(n),空间复杂度为O(1)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值