You got tons of method to crack this problem, especially if there is no requirement of time and space. See this article you will see some solutions and analysis.
The O(n) solution given in the article above is of great wit but it might not be a general choice. My solution is not so intuitive, but should be more general.
public int firstMissingPositive(int[] A) {
if (A.length == 0) {
return 1;
}
int j = A.length;
for (int i = 0; i < j; i++) {
int moveIn = A[i];
int moveOut;
while (moveIn > 0 && moveIn <= j && moveIn != A[moveIn-1]) {
moveOut = A[moveIn-1];
A[moveIn-1] = moveIn;
moveIn = moveOut;
}
}
int i;
for (i = 0; i < A.length; i++) {
if (A[i] != i+1) {
return i+1;
}
}
return i+1;
}
The key operation is within the while loop, it swaps integers to their correct positions. It's actually a in place but not stable counting sort. To ensure the swap is correct, I got inspired by the collision resolve method in cuckoo hashing:
When the for loop ends, the array should maintain following properties:
Thus in the second for loop:
The running time of all this kicked-and-kicking is O(n):
Every integers could only be accessed at most twice:
Or
Thus the running time is O(n).
I found an more beautiful solution that has a similar idea as mine but with more elegant and intuitive implementation.
To save your life, its key idea can be concluded as:
i), swap it with the integer at slot i;j) is not matched with the slot either, continue swap it with the integer at slot j;The procedures above maintain following invariant during their execution:
With these two properties, things are almost done.