Given an unsorted integer array, find the first missing positive integer.
For example,
Given [1,2,0]
return 3
,
and [3,4,-1,1]
return 2
.
Your algorithm should run in O(n) time and uses constant space.
最先想到的是先排序再查找,可是想到排序的复杂度是O(nlogn),就觉得没戏啊。然后,就处于停滞状态想不出好办法,可是看网上的答案用了,STL的sort也通过了,想不明白。
先分析下题目吧,unsorted integer array 可能有负数,0,正数,负数和0的first missing positive是1。正数就是,缺失的最小正数。另外数据可能是有重复的。
方法1:先排序在两两个比较是否相差1,若不是返回
int firstMissingPositive(int A[], int n) {
sort(A, A+n);
int res = 0;
int i = 0;
while (i<n && A[i]<=0) i++;
for (; i < n; i++)
{//注意:一看到序列就应该马上反应问题:是否有重复元素???
if (i>0 && A[i] == A[i-1]) continue;
if (A[i] - res != 1) return res+1;
else res = A[i];
}
return res+1;
}
方法2:利用下标保存相应的值
int firstMissingPositive(int A[], int n)
{
//逐个把A[i]放到A[i]位置的思想
//1:找到一个A[i]是在0到n范围的就放到相应位置
//2:没找到的直接跳过
//简单来说:就是把数字与下标对应起来
for(int i = 0; i != n; ++ i)
{
if(A[i] >= 0 && A[i] < n && A[A[i]] != A[i])
swap(A[i], A[A[i]]);
}
int k = 1;
while(k < n && A[k] == k) //按位置放置的过程中有某个点断开了,该点k
++ k;//k向后挪了一个;
if(n == 0 || k < n)//k<n,中间点断开,返回k;n==0,返回1
return k;
else if(A[0] == k)//k>=n,最后一个点断开,考虑到时从1开始判断下标,
//因为返回的是第一缺失的正数,0不是正数,缺失了也不能说明什么
return k+1;//A[0] == k;则返回k+1;
else
return k;//A[0] != k;则返回k
}