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
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
To find the smallest missing positive number, we'll simply check for each positive integer, starting from 1, to see if it's present in the input. We stop when we find the first positive integer that's not there.
Here's how the algorithm would work step-by-step:
def first_missing_positive_brute_force(numbers):
smallestPositiveInteger = 1
while True:
# Keep looping and incrementing until we find the missing positive.
if smallestPositiveInteger not in numbers:
#If the smallest positive integer is NOT in the input, return it
return smallestPositiveInteger
# Increment to check the next positive integer.
smallestPositiveInteger += 1
The core idea is to cleverly rearrange the input so the answer is sitting in a predictable spot. We leverage the input's structure to perform a more targeted search. This targeted rearrangement helps us avoid checking every single number in a separate search.
Here's how the algorithm would work step-by-step:
def first_missing_positive(numbers):
array_length = len(numbers)
if 1 not in numbers:
return 1
# Replace negatives, zeros, and nums > n with 1s
# After this conversion, nums will contain only positive numbers.
for i in range(array_length):
if numbers[i] <= 0 or numbers[i] > array_length:
numbers[i] = 1
# Use index as a hash key and number sign as a presence detector.
# For example, if nums[1] is negative, that means that the number `1`
# is present in the array.
# If nums[2] is positive, the number 2 is missing.
for i in range(array_length):
absolute_value = abs(numbers[i])
if absolute_value <= array_length:
numbers[absolute_value - 1] = - abs(numbers[absolute_value - 1])
# Now the index of the first positive number
# is equal to the first missing positive.
for i in range(array_length):
if numbers[i] > 0:
return i + 1
# If nums[i] > 0 is never triggered, that means
# that the answer is array_length + 1.
return array_length + 1
Case | How to Handle |
---|---|
Empty array or null input | Return 1, since the smallest missing positive is 1 when no positives are present. |
Array with only negative numbers or zeros | Return 1, as no positive numbers exist in the input. |
Array containing only the number 1 | Return 2, since 1 exists and 2 is the smallest missing positive. |
Array containing `n` where `n` is the size of the array, but not containing 1. | The algorithm should correctly identify 1 as the missing number after placing all positives in their respective positions. |
Array containing duplicates and a large range of numbers, including some positive numbers within the range [1, n] | The cyclic sort or in-place modification will handle duplicates correctly by skipping over them after one encounter and the relevant range allows finding smallest missing. |
Array containing all positive numbers from 1 to n | Return n + 1 since all numbers from 1 to n are present. |
Array containing extremely large positive and negative numbers | The algorithm will only operate on numbers within the range [1, n] and effectively ignore out-of-range numbers. |
Array containing only Integer.MAX_VALUE or Integer.MIN_VALUE | The algorithm correctly ignores Integer.MAX_VALUE and Integer.MIN_VALUE since they are outside the [1,n] range |