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.
For example:
nums = [1,2,0]
The numbers in the range [1,2]
are all in the array. Expected output is 3
.
nums = [3,4,-1,1]
1 is in the array but 2 is missing. Expected output is 2
.
nums = [7,8,9,11,12]
The smallest positive integer 1 is missing. Expected output is 1
.
Can you provide an implementation and explain the complexities?
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:
Let's say we're looking for the smallest missing positive number in a group. The brute force way means we check every possibility, starting from the smallest positive number.
Here's how the algorithm would work step-by-step:
def first_missing_positive_brute_force(numbers):
smallest_positive = 1
while True:
# Iterate until a missing positive is found.
if smallest_positive not in numbers:
# If smallest_positive is not in the list, return it.
return smallest_positive
# Increment to check the next positive integer.
smallest_positive += 1
The key idea is to rearrange the numbers within the original list such that the number at each position matches the position itself (plus one). This way, the first missing positive integer is simply the first position where the number doesn't match. After rearranging, we do a quick sweep to find the missing number.
Here's how the algorithm would work step-by-step:
def first_missing_positive(numbers):
list_size = len(numbers)
for i in range(list_size):
while 0 < numbers[i] <= list_size and numbers[i] != numbers[numbers[i] - 1]:
# Correct position calculation using index and value
correct_position = numbers[i] - 1
numbers[i], numbers[correct_position] = numbers[correct_position], numbers[i]
for i in range(list_size):
# Find the first index where the number is not in its correct place
if numbers[i] != i + 1:
return i + 1
# If all numbers are in place, the missing positive is the next integer.
return list_size + 1
Case | How to Handle |
---|---|
Empty input array | Return 1, as it's the smallest missing positive when there are no positive integers in the input. |
Input array contains only negative numbers and/or zeros | Return 1, as no positive numbers are present and 1 is the smallest missing positive. |
Input array contains only the number 1 | Return 2, as 1 is present and 2 is the next smallest positive. |
Input array contains the sequence 1, 2, 3, ..., n | Return n+1, as all numbers from 1 to n are present, so n+1 is missing. |
Input array contains Integer.MAX_VALUE | The algorithm should handle large positive integers without overflow, ensuring correct processing. |
Input array with duplicates, including multiple occurrences of 1 | Duplicates are handled correctly as we only need to check for the presence of numbers in the range [1, n], not their counts. |
Input array with both positive and negative numbers interspersed | The algorithm should correctly ignore negative numbers and focus on identifying the smallest missing positive within the range [1, n]. |
Input array containing large gaps between positive numbers (e.g., [1, 100000]) | The algorithm should work correctly even with large gaps, focusing on the presence of numbers in the range [1, n], where n is the array length. |