LeetCode41. 缺失的第一个正数

题目

给你一个未排序的整数数组,请你找出其中没有出现的最小的正整数。链接

思路

  • 普通方法,set直接淦(/dog)
class Solution {
    public int firstMissingPositive(int[] nums) {
        Set<Integer>set = new HashSet<>();
        int res = 1;
        for(int num : nums){
            set.add(num);
            if(set.contains(res)){
                res++;
            }
        }
        while(set.contains(res)){
                res++;
            }
        return res;
    }
}

借用评论区大佬的解释
原地哈希就相当于,让每个数字n都回到下标为n-1的家里。


而那些没有回到家里的就成了孤魂野鬼流浪在外,他们要么是根本就没有自己的家(nums[i] <= 0 || nums[i] > len),要么是自己的家被别人占领了(出现了重复)。


这些流浪汉被临时安置在下标为i的空房子里,之所以有空房子是因为房子i的主人i+1失踪了(数字i+1缺失)。
因此通过原地构建哈希让各个数字回家,我们就可以找到原始数组中重复的数字还有消失的数字。

首先确定结果的范围在[1, len + 1]之间,len为数组长度,当数组中的元素没有1时,结果为1,当数组中的元素涵盖了[1, len]中的所有数时,结果为len + 1


所以可以把数组下标和数组中的元素对应起来,当nums[i]∈[1, len]这个区间时,对应关系为nums[i] = i + 1,当不属于这个区间时不做操作。这样遍历一遍数组过后,即可通过下标确定数组中涵盖的[1, len]这个区间内的数。


再次遍历数组,遇到的第一个不满足对应关系的元素的下标加一i + 1即为结果,否则结果为len + 1

class Solution {
    public int firstMissingPositive(int[] nums) {
        int len = nums.length;
        for (int i = 0; i < len; i++) {
        	//这里用while是因为nums[i]交换过后的值可能仍然不满足nums[i] = i + 1
        	//所以需要继续交换,直到nums[i]不在[1,len]这个区间
            while (nums[i] >= 1 && nums[i] <= len && nums[nums[i] - 1] != nums[i]) {
                swap(nums, i, nums[i] - 1);
            }
        }
        //遍历找到第一个不满足对应关系的元素
        for (int i = 0; i < len; i++) {
            if (nums[i] != i + 1) {
                return i + 1;
            }
        }
        return len + 1;
    }

    private void swap(int[] nums, int i, int i1) {
        int temp = nums[i];
        nums[i] = nums[i1];
        nums[i1] = temp;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值