leetcode hard模式专杀leetcode 41 First Missing Positive

这题要求在O(n)时间复杂度,O(1)空间复杂度完成,摆明了只能扫描一次,并且几乎不能用额外的存储结构。

 

那么我的第一反应思路是用比特位,初始化一个全0的比特位图,然后逐个扫描数组元素,假设数组长度为x,则一次扫描这x元素,如果是碰到正数,则在该数对应的比特位放置1,例如如果是5,则在第5位置1。最后再从低位往高为扫描到第一个0的位置即为first missing positive

我是用的Java,里面有个很好的数据结构BitSet很快就写出来了这个逻辑,并且经过测试也是对的,可是没能通过leetcode OJ, 提示时内存消耗太大!

于是一想,我构建的这个比特位图,虽然计算逻辑很合理,但是有一点不太合理,就是这个比特位图可能非常稀疏,例如1,2,100000000,这样的位图,明明才3个元素,确踏马占了1亿个比特位,而同为3个长度的1,2,3这样的数列,却只需要3位长度的比特位图,这怎么行呢?于是想了一个办法,我就盯着前面例子,即两个长度为3的数列,看看能看出什么门道,仔细盯着想了一分钟,突然想起鸽巢原理的反面,就是说N个位置,你放N-1个球,总会有一个空着,那么如果输入的数列总长度为x,那么可能的first missing positive一定在前x+1个位置上,有了这个逻辑,所有的大于x+1的位置的设置,检查都不必做了,因为都是浪费。

 

于是得到如下更新版的代码:

public int firstMissingPositive(int[] nums) {
    BitSet bs = new BitSet();

    int maxBit = 0;
    for(int i=0;i<nums.length;i++){
        // if its positive intege
        if(nums[i]>0 && nums[i]<=nums.length){
            bs.set(nums[i]);
            if(maxBit<nums[i]){
                maxBit = nums[i];
            }
        }
    }

    for(int j = 1 ;j<=nums.length;j++){
        if(!bs.get(j)){
            return j;
        }
    }
    return nums.length+1;
}

 

很快就通过了OJ,嘿嘿,什么hard模式,不过如此

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值