Skip to main content

First Missing Positive

Problem

Given an unsorted integer array nums, return the smallest missing positive integer.

You must implement an algorithm that runs in O(n) time and uses constant extra space.

 

Example 1:

Input: nums = [1,2,0]
Output: 3

Example 2:

Input: nums = [3,4,-1,1]
Output: 2

Example 3:

Input: nums = [7,8,9,11,12]
Output: 1

 

Constraints:

  • 1 <= nums.length <= 5 * 105
  • -231 <= nums[i] <= 231 - 1

Solution

/**
* @param {number[]} nums
* @return {number}
*/
var firstMissingPositive = function(nums) {
// for nums[i] = n, set nums[n - 1] = n (use nums as a set)
for (let i = 0; i < nums.length; i++) {
const n = nums[i];
// n is in range and has not been processed before
if ((nums[n - 1] ?? n) !== n) {
nums[i] = nums[n - 1]; // swap elements
nums[n - 1] = n;
if (n !== i + 1) { // need to process swapped element
i--;
}
}
}

// find index where nums[i] !== i + 1
nums.push(0)
for (let i = 0; i < nums.length; i++) {
if (nums[i] !== i + 1) {
return i + 1;
}
}
};

Let nums contain l elements. Then by the pigeonhole principle, the first missing positive must be in the range of [1, l + 1] (ie. nums can hold at most [1, l] unique consecutive positive values starting from 1). Thus, we can use nums as a set, where for all value n that is in range of [1, l], set nums[n - 1] = n. This means, as we iterate through nums a second time, the first i + 1 where nums[i] !== i + 1 is the smallest missing positive.