这题很有意思。
如果不考虑空间复杂度,可以用一个数组tmp通过线性扫描A[],存放1-n的出现情况,然后再扫描一次tmp即可。
但是如果O(1)空间复杂度的话,就得在原地保存信息。
基本思想是:如果i存在,则令A[i-1] = n+1。但是这样A[i-1]原来的信息就丢失了,所以用一个变量tmp保存A[i-1]的值,再判断A[tmp-1]是否为n+1,如果不是,则令A[tmp-1]为n+1,同时自然需要保存A[tmp-1]原有值,这样循环直到A[tmp-1]为n+1停止。
class Solution {
public:
int firstMissingPositive(int A[], int n) {
if(n<1)
return 1;
for(int i=0;i<n;++i)
if(A[i]==(n+1))
++A[i];
for(int i=0;i<n;++i){
if(A[i]<=0 || A[i]>n)
continue;
int tmp = A[A[i]-1];
A[A[i]-1] = n+1;
while(tmp<=n &&tmp>0 && A[tmp-1]!=(n+1)){
int tmp2 = A[tmp-1];
A[tmp-1] = n+1;
tmp = tmp2;
}
}
int i=0;
while(A[i]==(n+1))
++i;
return i+1;
}
};
啊!后来看到一个更精妙的解法。要保存原有信息可以将其转为负值用于保存结果,取绝对值即可得到其原值。
class Solution {
public:
int firstMissingPositive(int A[], int n) {
if(n<1)
return 1;
for(int i=0;i<n;++i)
if(A[i]<=0)
A[i] = n+2;
for(int i=0;i<n;++i){
if(abs(A[i])>n)
continue;
A[abs(A[i])-1] = -abs(A[abs(A[i])-1]);
}
int i=0;
while(A[i]<0)
++i;
return i+1;
}
};