leetcode_41_缺失的第一个正数

题目

在这里插入图片描述

分析

看到查找某个数,就应该考虑哈希。这里用HashMap不合适,输入量本身就是一个数组,可以借助于数组的下标来达到哈希的效果。可以在原数组进行操作;也可以新开辟一个数组进行操作。新开辟数组代码实现会更简单哦。

  • 首先正整数是从1开始的,假设数组长度为n, 那么缺失的第一个最大正整数为n+1, 即数组中已经存储了1到n的值,且没有重复元素。那么首先,我们应该先将数组中大于n+1的数和小于1的数给找出来,然后从剩下的数中来判断缺失的第一个正整数是谁?因为我们要向借助于数组的下标来达到Hash索引的效果,那么就需要将各个元素的值设置的0-n-1之间,而最小正整数为1 ,数组的下标又是从0开始的,因此将数组下标0用于表示元素n.
  • OK了。现在要解决的问题就是将不在1-n之间的数转换到1到n之间,那么转换为几呢?? 转换为1 !!! 为什么呢? 因为我们可以先遍历一遍数组,看是否又元素1的存在,如果不存在,也不用后续的操作的,直接返回1即可。 如果转换为别的数字是不会有这个效果的。
  • 然后依次遍历,将元素值与数组的下标对应,比如,元素值2,找到下标为2的元素,将其取反,表示元素2存在于数组中,前面已经说了元素n与下标0对应。这样存在于数组中的元素就会将其对应的下标中的元素取反了,转换为了负数,我们就可以依次查看哪一下标中的元素值还是正数,就说明此下标正是缺失的第一个正整数,因为元素中不存在该下标值,故未取反。如果都是负数,那么说明1到n都在数组中,返回n+1即可。

代码

利用原数组:

class Solution {
    public int firstMissingPositive(int[] nums) {  
        boolean flag=true;
        for(int i=0;i<nums.length;i++)
            if(nums[i]==1){
                flag=false;
                break;
            }    
        if(flag)
            return 1;
        if(nums.length==1)
            return 2;
        for(int i=0;i<nums.length;i++)
            if(nums[i]<=0||nums[i]>nums.length)
                nums[i]=1;
        for(int i=0;i<nums.length;i++){
            int a=Math.abs(nums[i]);
            if(a==nums.length)
                nums[0]=-Math.abs(nums[0]);
            else
                nums[a]=-Math.abs(nums[a]);
        }
        for(int i=1;i<nums.length;i++){
            if(nums[i]>0)
                return i;
        }
        if(nums[0]>0)
            return nums.length;
        return nums.length+1;
    }
}

开辟新数组:

class Solution {
    public int firstMissingPositive(int[] nums) {
        int []a=new int[nums.length+1];
        for(int i=0;i<nums.length;i++){
            if(nums[i]>0&&nums[i]<=nums.length)
                a[nums[i]]=1;
        }
        for(int i=1;i<a.length;i++){
            if(a[i]!=1)
                return i;
        }
        return a.length;
    }    
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值