First Missing Positive
Smallest missing positive integer — cyclic sort placing each value at index value-1.
3 min read
cyclic-sort
Problem#
Return the smallest positive integer missing from nums. O(n) time, O(1) extra space.
Examples#
[1,2,0]→3[3,4,-1,1]→2[7,8,9,11,12]→1
Constraints#
1 <= n <= 10^5.
Approach#
Cyclic sort: for each i, swap nums[i] to its “home” position nums[i] - 1 if it’s in [1, n] and not already there. Then scan for the first i where nums[i] != i + 1.
Solution#
class Solution {public: int firstMissingPositive(vector<int>& nums) { int n = nums.size(); for (int i = 0; i < n; ) { if (nums[i] >= 1 && nums[i] <= n && nums[nums[i] - 1] != nums[i]) { swap(nums[i], nums[nums[i] - 1]); } else { ++i; } } for (int i = 0; i < n; ++i) if (nums[i] != i + 1) return i + 1; return n + 1; }};func firstMissingPositive(nums []int) int { n := len(nums) for i := 0; i < n; { if nums[i] >= 1 && nums[i] <= n && nums[nums[i]-1] != nums[i] { nums[i], nums[nums[i]-1] = nums[nums[i]-1], nums[i] } else { i++ } } for i := 0; i < n; i++ { if nums[i] != i+1 { return i + 1 } } return n + 1}from typing import List
class Solution: def firstMissingPositive(self, nums: List[int]) -> int: n = len(nums) i = 0 while i < n: if 1 <= nums[i] <= n and nums[nums[i] - 1] != nums[i]: j = nums[i] - 1 nums[i], nums[j] = nums[j], nums[i] else: i += 1 for i in range(n): if nums[i] != i + 1: return i + 1 return n + 1var firstMissingPositive = function(nums) { const n = nums.length; let i = 0; while (i < n) { if (nums[i] >= 1 && nums[i] <= n && nums[nums[i] - 1] !== nums[i]) { const j = nums[i] - 1; [nums[i], nums[j]] = [nums[j], nums[i]]; } else { i++; } } for (let i = 0; i < n; i++) { if (nums[i] !== i + 1) return i + 1; } return n + 1;};class Solution { public int firstMissingPositive(int[] nums) { int n = nums.length; for (int i = 0; i < n; ) { if (nums[i] >= 1 && nums[i] <= n && nums[nums[i] - 1] != nums[i]) { int j = nums[i] - 1; int tmp = nums[i]; nums[i] = nums[j]; nums[j] = tmp; } else { i++; } } for (int i = 0; i < n; i++) { if (nums[i] != i + 1) return i + 1; } return n + 1; }}function firstMissingPositive(nums: number[]): number { const n = nums.length; let i = 0; while (i < n) { if (nums[i] >= 1 && nums[i] <= n && nums[nums[i] - 1] !== nums[i]) { const j = nums[i] - 1; [nums[i], nums[j]] = [nums[j], nums[i]]; } else { i++; } } for (let k = 0; k < n; k++) { if (nums[k] !== k + 1) return k + 1; } return n + 1;}Editorial#
The answer is always in [1, n+1]. Cyclic sort places every value in [1, n] at index value - 1. Anything else (out-of-range, duplicate) stays — those indices remain mismatched, and the first one is the answer. The nums[nums[i] - 1] != nums[i] guard prevents infinite swap loops on duplicates.
Complexity#
- Time: O(n) amortized.
- Space: O(1).
Concept revision#
Related#