2975 字
约 9 分钟
7
LeetCode刷题Java版041.缺失的第一个整数
无标签

LeetCode刷题Java版041.缺失的第一个整数

作者:沉默王二
发布时间:2022-09-14T19:23:17.244+0800


041.缺失的第一个整数

题意

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

请你实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案。

难度

困难

示例

输入:nums = [1,2,0]

输入:nums = [3,4,-1,1]输出:2

分析

本题如果没有 只使用常数级别额外空间 这个限制条件的话,非常容易解决,只需要额外开一个哈希表来存储使用过的数字就可以了。

但是很遗憾,有这个限制条件。

不过没关系,我们先来看看题目要求我们做的事情——找出没有在nums[]出现的最小正整数。

我们约定一下,n为nums[]数组的长度。

那是不是有这样一种情况,就是1 - n中的每个整数,都在nums[]中出现过一次。

即——nums[]是一个n的排列。

这样子的话答案肯定就是n + 1!

因为1 - n全都出现过了,只有n + 1没有出现过。

也就是说——除了1-n之外的数字,即小于等于0的数和大于n的数字,对我们的 ”帮助“ 其实是一样的,所以我们可以把他们变成同一个数字,这里先暂定为n + 1。

再来看看我们手中现在有的东西——nums[](只剩下正整数了)以及常数级别的额外空间。

因为我们把所有的0和负数都转化为了n + 1。

想一想哈希表——就是利用0和1两种状态来表示这个数字是否存在的。

那么我们是不是也可以找找nums[]能不能有相应的两种状态呢?

有!那就是正数和负数两个状态,因为我们先前已经把所有的负数变成正数了,所以这就是新的哈希表的状态。利用nums[x]的正负,来表示x是否存在。正数表示不存在,负数表示存在。

所以这时候,我们的哈希表就浮现出来了。

如果x > n呢?不着急,直接忽略它就好了,因为它不可能成为答案,跟上面去除负数的原理是一样的。

最后再扫描一遍nums[],第一个正整数,就是答案!

最后注意一下,因为nums[]只有0-(n - 1),所以标记的时候记得减一即可。

class Solution {

        for(int i = 0;i < nums.length;i++){            if(nums[i] <= 0)                nums[i] = nums.length + 1;        }        for(int i = 0;i < nums.length;i++){            if(nums[i] > nums.length)                continue;            nums[Math.abs(nums[i]) - 1] = -Math.abs(nums[Math.abs(nums[i]) - 1]);        }        int ans = nums.length + 1;        for(int i = 0;i < nums.length;i++)            if(nums[i] > 0){                ans = i + 1;                break;            }        return ans;    }}

因为只扫描了三遍数组,所以时间复杂度为。运行效率也不负所望。

总结

当题目限制我们在一定的条件下的时候,一定要想尽一切办法利用可以利用的资源,这也是这道困难题给我们的启发,本来如果是没有限制的话,就是一道简单题,只需要用哈希表记录即可,但是限制了之后,就需要我们利用眼前的东西,来实现平时简单模式下的功能。

力扣链接:https://leetcode.cn/problems/first-missing-positive/

一步一个脚印

不积跬步无以至千里,不积小流无以成江海。LeetCode - 100天从算法小白到卷王正式启动了,我们计划周一到周五至少每天更新一篇,周六周日更新一篇,目标 300 道 LeetCode 经典题。

PDF 版本目前只针对**二哥编程星球 的球友开放,如果你也想一起打卡学习算法的话,戳链接 **加入我们吧。

一个人可以走得很快,但一群人才能走得更远。二哥编程星球 (目前已有 790 多名球友加入)里面的每个球友都非常的友善,除了鼓励你,还会给你提出合理的建议,一起冲!

041.缺失的第一个整数

题意

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

请你实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案。

难度

困难

示例

输入:nums = [1,2,0]

输入:nums = [3,4,-1,1]输出:2

分析

本题如果没有 只使用常数级别额外空间 这个限制条件的话,非常容易解决,只需要额外开一个哈希表来存储使用过的数字就可以了。

但是很遗憾,有这个限制条件。

不过没关系,我们先来看看题目要求我们做的事情——找出没有在nums[]出现的最小正整数。

我们约定一下,n为nums[]数组的长度。

那是不是有这样一种情况,就是1 - n中的每个整数,都在nums[]中出现过一次。

即——nums[]是一个n的排列。

这样子的话答案肯定就是n + 1!

因为1 - n全都出现过了,只有n + 1没有出现过。

也就是说——除了1-n之外的数字,即小于等于0的数和大于n的数字,对我们的 ”帮助“ 其实是一样的,所以我们可以把他们变成同一个数字,这里先暂定为n + 1。

再来看看我们手中现在有的东西——nums[](只剩下正整数了)以及常数级别的额外空间。

因为我们把所有的0和负数都转化为了n + 1。

想一想哈希表——就是利用0和1两种状态来表示这个数字是否存在的。

那么我们是不是也可以找找nums[]能不能有相应的两种状态呢?

有!那就是正数和负数两个状态,因为我们先前已经把所有的负数变成正数了,所以这就是新的哈希表的状态。利用nums[x]的正负,来表示x是否存在。正数表示不存在,负数表示存在。

所以这时候,我们的哈希表就浮现出来了。

如果x > n呢?不着急,直接忽略它就好了,因为它不可能成为答案,跟上面去除负数的原理是一样的。

最后再扫描一遍nums[],第一个正整数,就是答案!

最后注意一下,因为nums[]只有0-(n - 1),所以标记的时候记得减一即可。

class Solution {

        for(int i = 0;i < nums.length;i++){            if(nums[i] <= 0)                nums[i] = nums.length + 1;        }        for(int i = 0;i < nums.length;i++){            if(nums[i] > nums.length)                continue;            nums[Math.abs(nums[i]) - 1] = -Math.abs(nums[Math.abs(nums[i]) - 1]);        }        int ans = nums.length + 1;        for(int i = 0;i < nums.length;i++)            if(nums[i] > 0){                ans = i + 1;                break;            }        return ans;    }}

因为只扫描了三遍数组,所以时间复杂度为。运行效率也不负所望。

总结

当题目限制我们在一定的条件下的时候,一定要想尽一切办法利用可以利用的资源,这也是这道困难题给我们的启发,本来如果是没有限制的话,就是一道简单题,只需要用哈希表记录即可,但是限制了之后,就需要我们利用眼前的东西,来实现平时简单模式下的功能。

力扣链接:https://leetcode.cn/problems/first-missing-positive/

一步一个脚印

不积跬步无以至千里,不积小流无以成江海。LeetCode - 100天从算法小白到卷王正式启动了,我们计划周一到周五至少每天更新一篇,周六周日更新一篇,目标 300 道 LeetCode 经典题。

PDF 版本目前只针对**二哥编程星球 的球友开放,如果你也想一起打卡学习算法的话,戳链接 **加入我们吧。

一个人可以走得很快,但一群人才能走得更远。二哥编程星球 (目前已有 790 多名球友加入)里面的每个球友都非常的友善,除了鼓励你,还会给你提出合理的建议,一起冲!

041.缺失的第一个整数

题意

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

请你实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案。

难度

困难

示例

输入:nums = [1,2,0]

输入:nums = [3,4,-1,1]输出:2

分析

本题如果没有 只使用常数级别额外空间 这个限制条件的话,非常容易解决,只需要额外开一个哈希表来存储使用过的数字就可以了。

但是很遗憾,有这个限制条件。

不过没关系,我们先来看看题目要求我们做的事情——找出没有在nums[]出现的最小正整数。

我们约定一下,n为nums[]数组的长度。

那是不是有这样一种情况,就是1 - n中的每个整数,都在nums[]中出现过一次。

即——nums[]是一个n的排列。

这样子的话答案肯定就是n + 1!

因为1 - n全都出现过了,只有n + 1没有出现过。

也就是说——除了1-n之外的数字,即小于等于0的数和大于n的数字,对我们的 ”帮助“ 其实是一样的,所以我们可以把他们变成同一个数字,这里先暂定为n + 1。

再来看看我们手中现在有的东西——nums[](只剩下正整数了)以及常数级别的额外空间。

因为我们把所有的0和负数都转化为了n + 1。

想一想哈希表——就是利用0和1两种状态来表示这个数字是否存在的。

那么我们是不是也可以找找nums[]能不能有相应的两种状态呢?

有!那就是正数和负数两个状态,因为我们先前已经把所有的负数变成正数了,所以这就是新的哈希表的状态。利用nums[x]的正负,来表示x是否存在。正数表示不存在,负数表示存在。

所以这时候,我们的哈希表就浮现出来了。

如果x > n呢?不着急,直接忽略它就好了,因为它不可能成为答案,跟上面去除负数的原理是一样的。

最后再扫描一遍nums[],第一个正整数,就是答案!

最后注意一下,因为nums[]只有0-(n - 1),所以标记的时候记得减一即可。

class Solution {

        for(int i = 0;i < nums.length;i++){            if(nums[i] <= 0)                nums[i] = nums.length + 1;        }        for(int i = 0;i < nums.length;i++){            if(nums[i] > nums.length)                continue;            nums[Math.abs(nums[i]) - 1] = -Math.abs(nums[Math.abs(nums[i]) - 1]);        }        int ans = nums.length + 1;        for(int i = 0;i < nums.length;i++)            if(nums[i] > 0){                ans = i + 1;                break;            }        return ans;    }}

因为只扫描了三遍数组,所以时间复杂度为。运行效率也不负所望。

总结

当题目限制我们在一定的条件下的时候,一定要想尽一切办法利用可以利用的资源,这也是这道困难题给我们的启发,本来如果是没有限制的话,就是一道简单题,只需要用哈希表记录即可,但是限制了之后,就需要我们利用眼前的东西,来实现平时简单模式下的功能。

力扣链接:https://leetcode.cn/problems/first-missing-positive/

一步一个脚印

不积跬步无以至千里,不积小流无以成江海。LeetCode - 100天从算法小白到卷王正式启动了,我们计划周一到周五至少每天更新一篇,周六周日更新一篇,目标 300 道 LeetCode 经典题。

PDF 版本目前只针对**二哥编程星球 的球友开放,如果你也想一起打卡学习算法的话,戳链接 **加入我们吧。

一个人可以走得很快,但一群人才能走得更远。二哥编程星球 (目前已有 790 多名球友加入)里面的每个球友都非常的友善,除了鼓励你,还会给你提出合理的建议,一起冲!

            知识星球
            
    
    
        
        扫码加入星球
        查看更多优质内容
    
    https://wx.zsxq.com/mweb/views/joingroup/join_group.html?group_id=15522885221412
LeetCode刷题Java版041.缺失的第一个整数
https://clxhxhhr.top/posts/2505/
作者
clxstart
发布于
2026-09-19
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。