leetcode题集: 41. First Missing Positive

24 篇文章 0 订阅

题目大意:给定一个乱序的整型数组,找出最小的缺失的正整数。 简单来说,就是找出数组中没有的最小正整数

题目分析:题目的难点在于他的要求,要求O(n)时间和常量空间。这下就直接把排序(时间复杂度不满足)和额外数组打表(空间复杂度不满足)两个方法给排除了,这是我第一反应能想到的两个方法。简单解释一下打表:常用的空间换时间方法,即用一个数组记录,数组位置上的元素放的就是 位置的值,也即 a[i] = i 或者 a[i] = i+1;总的来说,后面一般是 关于位置 i 的表达式。知道了打表,回到题目,加入不限制空间的话,那么很简单就能写出伪代码:

int a[input.size] = {0}
for i=0...input.size-1
    if( input[i]>0 && input[i]<=input.size )    // 负数和超出数组大小的不要
        // a[i] = i + 1, 边界a[0] = 1; a[input.size-1] = input.size
        a[input[i] - 1] = input[i]

for i=0...input.size-1
    if(a[i] != i+1 ) return i+1;    // a[i]没有存储 i+1,则缺失

//末尾返回
return input.size+1

这个时间复杂度倒是满足了,要是不要额外的空间就好了!想到这里,思路应该清晰了。打表可不可以不开额外的数组呢?当然是可以的!就用原来的数组就好,不就是要相应位置存储相应位置数值嘛,交换就行了。直接上代码:

class Solution {
public:
    int firstMissingPositive(vector<int>& nums) {
        for(int i=0;i<nums.size();){
        // 交换的条件:数值在数组范围内;自己位置存储不对,目标交换位置的存储也不对;
            if(nums[i]>0 && nums[i]<=nums.size() && nums[i]!=i+1 && 
               nums[nums[i]-1]!=nums[i]){ 
                swap(nums[nums[i]-1], nums[i]);
            } else i++;    // 因为交换之后当前 i 存储的数值改变,需要进一步判断是否需要增加 i
        }
        // for(auto item: nums) cout <<item <<" ";
        // cout <<endl;
        for(int i=0;i<nums.size();i++){    // 已经交换好的数组
            if(nums[i]!=i+1) return i+1;    // 碰到第一个不对,就是你了!
        }
        return nums.size()+1;
    }
};

结果有点喜人 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值