Given an unsorted integer array nums. Return the smallest positive integer that is not present in nums.
You must implement an algorithm that runs in O(n) time and uses O(1) auxiliary space.
Example 1:
Input: nums = [1,2,0]
Output: 3
Explanation: The numbers in the range [1,2] are all in the array.
Example 2:
Input: nums = [3,4,-1,1]
Output: 2
Explanation: 1 is in the array but 2 is missing.
Example 3:
Input: nums = [7,8,9,11,12]
Output: 1
Explanation: The smallest positive integer 1 is missing.
Constraints:
1 <= nums.length <= 105
-231 <= nums[i] <= 231 - 1
Solutions
Solution 1: In-place Swap
Thinking
The first idea is a hash set of seen numbers, then probe \(1, 2, 3, \ldots\). Correct and \(O(n)\) time, but \(O(n)\) extra space. The problem asks for \(O(n)\) time and constant extra space; \(n \le 10^5\) makes the set fail the space bound.
The bottleneck is recording whether \(1..n\) appear with extra memory. The missing positive must lie in \([1, n+1]\), so we only care about \(1..n\) — the array indices themselves can be that table.
Swap value \(x\) to index \(x-1\) when \(x \in [1, n]\). In-place swap turns the array into a hash; one more scan finds the first hole.
We assume the length of the array \(nums\) is \(n\), then the smallest positive integer must be in the range \([1, .., n + 1]\). We can traverse the array and swap each number \(x\) to its correct position, that is, the position \(x - 1\). If \(x\) is not in the range \([1, n + 1]\), then we can ignore it.
After the traversal, we traverse the array again. If \(i+1\) is not equal to \(nums[i]\), then \(i+1\) is the smallest positive integer we are looking for.
The time complexity is \(O(n)\), where \(n\) is the length of the array. The space complexity is \(O(1)\).