欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 社会 > 缺失的第一个正整数

缺失的第一个正整数

2025/10/22 9:43:54 来源:https://blog.csdn.net/zhiyikeji/article/details/148760805  浏览:    关键词:缺失的第一个正整数

继续每日一题

今天给大家带来一道将数组视为哈希表的算法

题目描述:

给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数。
请你实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案。

题目示例:
在这里插入图片描述

由于题目要求我们「只能使用常数级别的空间」,而要找的数一定在 [1, N + 1] 左闭右闭(这里 N 是数组的长度)这个区间里。因此,我们可以就把原始的数组当做哈希表来使用。事实上,哈希表其实本身也是一个数组;

最小正整数从1开始,那么没有出现的最小正整数一定在1到n+1之间(因为如果1到n都出现了,那么答案就是n+1)

所以我们可以只考虑数组中的1到n之间的数,负数、0和大于n的数可以忽略(因为它们不影响1到n之间的最小缺失正整数)。

考虑到对时间和空间复杂度的要求,我们可以采用原地置换,具体流程通过文字描述不太直观,下面通过一个case给大家描述一下:

数组 [3,4,-1,1]

  • i=0,nums[0]=3,它应该在位置2(即下标2),交换nums[0]和nums[2]:得到[-1,4,3,1]
    然后i=0,此时nums[0]=-1,不在1到4范围内,跳过。

  • i=1,nums[1]=4,它应该在位置3,交换nums[1]和nums[3]:得到[-1,1,3,4]
    然后i=1,此时nums[1]=1,它应该在位置0,但是位置0是-1,交换:得到[1,-1,3,4]
    然后i=1,现在nums[1]=-1,跳过。

  • i=2,nums[2]=3,在位置2(正确),跳过。

  • i=3,nums[3]=4,在位置3(正确),跳过。

然后遍历数组

  • i=0,num[0]=1(正确);
  • i=1,num[1]=-1,但实际上i=1,对应的数是2,所以返回i+1

但是在置换过程中可能会存在当前位置和要置换的位置的数值是相同的,导致死循环,所以在置换之前还需要比较两个值是否相同

核心逻辑如下:

  • 当前元素:currentVal=nums[i]
  • 当前元素需要在的位置:index=currentVal - 1,因为数组下标从0开始,所以需要减一
  • 要置换的元素:nums[index]
while (true) {int currentVal = nums[i];//当前元素需要置换到该位置,数组下标从0开始,所以需要减一int changeIndex = currentVal - 1;int needChangeVal = nums[changeIndex];if (currentVal < 1 || currentVal > n) {//不在有效范围无需置换break;}int needChangeVal = nums[changeIndex];if (currentVal == needChangeVal) {//两个数字相等,无需置换break;}nums[i] = needChangeVal;nums[changeIndex] = currentVal;}

完整代码如下:

    public static int firstMissingPositive(int[] nums) {int n = nums.length;for (int i = 0; i < n; i++) {while (true) {int currentVal = nums[i];//当前元素需要置换到该位置,数组下标从0开始,所以需要减一int changeIndex = currentVal - 1;if (currentVal < 1 || currentVal > n) {//不在有效范围无需置换break;}int needChangeVal = nums[changeIndex];if (currentVal == needChangeVal) {//两个数字相等,无需置换break;}nums[i] = needChangeVal;nums[changeIndex] = currentVal;}}for (int i = 0; i < n; i++) {int currentVal = nums[i];if (currentVal != i + 1) {return i + 1;}}//如果都存在则返回 n+1return n + 1;}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com