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.
刚开始的方法:
class Solution {
public:
int firstMissingPositive(int A[], int n) {
bool here[99999];
for (int i = 0; i < 99999; i++) {
here[i] = false;
}
for (int i = 0; i < n; i++) {
if (A[i] > 0)
here[(A[i] % 99999)] = true;
}
for (int i = 1; i < 99999; i++) {
if (here[i] == false)
return i;
}
return 99999 + 1;
}
};
尽管是常数空间,但是这个常数会经常大于n
后来在discuss里面看到的方法:
首先将数组处理,使得A[i] = i;
这里看似两重循环,但是每一次的内部循环,都将使得A[target] = target,这样内部循环的控制条件之一target != A[target]将会变得越来越苛刻,对于一个n长度的数组,A[target] = target在最坏的情况下也只需n步即可完成;
最后再扫一遍,发现A[i] != i的即为所求;
但在这里,数组的起始点是0,导致少了一位可使用的位置,因而用变量last来指代A[n]。
class Solution {
public:
int firstMissingPositive(int A[], int n) {
if (n == 0) return 1;
int last;
for (int i = 0; i < n; i++) {
int target = A[i];
while (0 <= target && target < n && target != A[target]) {
swap(target, A[target]);
}
if (target == n) last = target;
}
for (int i = 1; i <= n; i++) {
if (i == n) {
if (last != i) return i;
else return n + 1;
}
if (A[i] != i) return i;
}
return n;
}
};