题意是给一个未排序的数组,可能包含正数、负数、0。求第一个未出现的正数,例如[1, 2, 0],由于第一个未出现的正数是3,返回3;[3, 4, -1, 1]第一个未出现的正数是2,返回2。算法要求O(n)时间复杂度及常数空间复杂度。
// Stable unguarded_partition, always put t to the left side.
// If t is larger than [begin, end), return end.
// If t is smaller than [begin, end), return begin.
template<typename T>
T *unguarded_partition(T *begin, T *end, T t)
{
while (true)
{
while (*begin <= t && begin < end) ++begin;
--end;
while (*end > t && begin < end) --end;
if (!(begin < end)) return begin;
iter_swap(begin, end);
++begin;
}
}
int firstMissingPositive(int A[], int n)
{
if (A == NULL || n <= 0) return 1;
// positive[0] is 0 or the last negative number or invalid position.
int *positive = unguarded_partition(A, A + n, 0) - 1;
int positive_len = A + n - positive;
// Make sure not access positive[0].
for (int i = 1; i < positive_len; ++i)
{
int val = abs(positive[i]);
// Flip positive[val] to negative.
if (val > 0 && val < positive_len && positive[val] > 0)
{
positive[val] = -positive[val];
}
}
// The first positive index is the first missing positive number.
for (int i = 1; i < positive_len; ++i)
{
if (positive[i] > 0)
{
return i;
}
}
// Or the first missing positive num is not in [1, positive)
return positive_len;
}