lc41寻找缺失第一个的正数解法超详细解释

在这里插入图片描述
本体的目标是找到数组中若按顺序排列后缺少的最小的正数
在这里插入图片描述
本题的难点在于如何使用常数级的空间以及O(n)级别的时间复杂度实现。
首先需要明确的是,缺失的最小正整数一定出现在[1, nums.length+1]范围内,若数组中包含[1, nums.length]的数字,此时数组若排序则是[1, nums.length]连续的,则缺失的最小正整数为nums.length+1,其他情况(即数组排序后不连续)的最小缺失正整数均在[1, num.length]范围内。
由于时间和空间复杂度的限制,我们需要将数组本身进行一些处理,使其变成哈希存储的形式。
整个过程分成两步:
1.第一次遍历整个数组,将nums[i]放在nums[i]-1的索引处,即映射关系是num[i] = i + 1。处理的方式是,交换nums[i]和nums[nums[i]-1]两位置的数字。交换之后,nums[i]的数值仍可能需要交换到正确位置,因此用一个while循环,循环的条件如下:
1 <= nums[i] <= nums.length
nums[i] != nums[nums[i] - 1]
我们的目的是将处在[1, nums.length]范围内的正数放在对应的索引处,超出此范围的数字无需考虑,第二个条件用于避免在某些数字有重复或已经在正确位置上的数字仍然进入while循环交换位置。
举个简单例子:
在这里插入图片描述在这里插入图片描述
遍历完成之后,数组中处在[1, nums.length]范围内的数字全部放在正确的哈希索引位置,接着进行第二步的遍历即可。
2.第二次遍历即遍历已经处理完成的数组,数组中所有处于[1. num.length]范围内的数值,均在对应的位置上,因此从头开始遍历,找到第一个不满足映射关系的索引,加一之后即为缺失的最小的数值。
完整代码如下:

 public static int firstMissingPositive(int[] nums) {
        // 第一遍遍历将数组映射为哈希表的形式
        for (int i=0; i < nums.length;i++) {
            // 将[1, N]的数字x映射到数组中x-1的位置上
            while (nums[i] >= 1 && nums[i] <= nums.length && nums[nums[i] - 1] != nums[i]) {
                int tmp = nums[nums[i] - 1];
                nums[nums[i] - 1] = nums[i];
                nums[i] = tmp;
            }
        }
        for (int i = 0; i < nums.length; i++){
            if (nums[i] != i + 1){
                return i + 1;
            }
        }
        return nums.length+1;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值