找到缺失的第一个正整数

时间:2019-10-18
本文章向大家介绍找到缺失的第一个正整数,主要包括找到缺失的第一个正整数使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

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

示例 1:

输入: [1,2,0]
输出: 3

示例 2:

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

示例 3:

输入: [7,8,9,11,12]
输出: 1

你的算法的时间复杂度应为O(n),并且只能使用常数级别的空间O(1)。

这道题如果不要求时间复杂度为O(n)和空间O(1)的话,其实很简单的,可以先对数组做一个排序,然后从小到大的找第一个缺失的正整数。但是排序的时间复杂度至少也是O(nlogn)。所以不能用排序的方法来进行查找。

对一个数组而言,其实最小的值排列就是[1…..length]的值,这个怎么理解呢。比如长度为4的数组,那么这个数组最小整数排列就是1,2,3,4。也就是长度为4的数组能容纳的最小数就是1,2,3,4。那么对于任意一个长度为4的数组,缺失的最小正整数就一定在[1-length]之间的值。对于索引而言就是最小正整数一定存在于[1-index+1]的范围。

既然最小的值和数组的索引有如此的关系,那么我们就可以借助索引的方法,将各个值放入到其对应的索引中去。比如i=4, num[i]=3, 那么我们就该把3和i=2的值进行互换。至于值超出数组长度或者负数,则不用去管。这样能保证在数组长度范围内的数都在起索引的位置上。变相起到了排序的功能。

用一个长度为5的数组来看下:

-1, 3, 5, 2, 7

Step1: i=0; num[i]=-1。不处理.  i++

Step2: i=1; num[i]=3<5, 因此放入对应的索引位置,也就是3-1=2, 将num[1]和num[2]对换。数组变成-1,5,3,2,7.

Step3:i=2;num[i]=3 正好对应其索引位置,不处理,i++;

Step4:i=3 num[3]=2<5 放入对应的索引位置,也就是2-1=1, 将num[3]和num[1]对换。

数组变成-1,2,3,5,7

Step5:i=4 num[4]=7>5 不处理

最终的数组变成-1,2,3,5,7。 那么从数组开始判断,看下num[i]是否是和i+1相等。如果不是,则缺失的最小正整数就是i+1。 上面的数组明显就可以得出缺失的最小正整数就是0+1=1。

代码如下:

int firstMissingPositive(int a[], int len)
{
	int i,temp;
	i = 0;
	while(i<len)
	{
		if (a[i] < 0 || a[i] > len || a[a[i] - 1] == a[i])
		{
			i++;
		}
		else
		{
			temp = a[a[i] - 1];
			a[a[i] - 1] = a[i];
			a[i] = temp;
			i++;
		}
	}
	for (i = 0; i < len; i++)
	{
		if (a[i] != i + 1)
			return i + 1;
	}
	return -1;
}

  

原文地址:https://www.cnblogs.com/zhanghongfeng/p/11696533.html