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]
Output: 3
Explanation: The numbers in the range [1,2] are all in the array.nums = [3,4,-1,1]
Output: 2
Explanation: 1 is in the array but 2 is missing.nums = [7,8,9,11,12]
Output: 1
Explanation: The smallest positive integer 1 is missing.Explain your approach, analyze the time and space complexity, and handle edge cases.
The most straightforward approach is to iterate from 1 and check for the presence of each positive integer in the array. This continues until we find the first missing positive integer.
def first_missing_positive_naive(nums):
n = len(nums)
for i in range(1, n + 2):
if i not in nums:
return i
O(n*m), where n is the range we search in and m is the length of the array. In the worst case scenario, we might iterate through a range almost as large as the array itself for each check.
O(1), because no extra space scales with the input size is used.
The optimal solution uses the input array itself as a hash table. The basic idea is that if k
is present in the array, we try to place it at index k-1
. Then we iterate through the array, and the first index i
where nums[i] != i + 1
is the index where the missing positive number is i + 1
.
n
by 1.a
. Be careful with duplicates: do sign change only once.nums[0] > 0
, return n + 1
. If during the previous steps you didn't find the positive element in nums
, that means that the answer is n + 1
.nums[0] < 0
, return n + 2
. This implies all numbers from 1 to n
were present.def first_missing_positive(nums):
n = len(nums)
# Base case.
if 1 not in nums:
return 1
# Replace negative numbers, zeros, and numbers larger than n by 1.
# After this conversion, nums will contain only positive numbers.
for i in range(n):
if nums[i] <= 0 or nums[i] > n:
nums[i] = 1
# Use the index as a hash key and the sign of the number 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(n):
a = abs(nums[i])
# If you meet number a in the array, change the sign of the a-th element.
# Be careful with duplicates: do sign change only once.
if a == n:
nums[0] = - abs(nums[0])
else:
nums[a] = - abs(nums[a])
# Now the index of the first positive number is equal to the first missing positive.
for i in range(1, n):
if nums[i] > 0:
return i
if nums[0] > 0:
return n
return n + 1
O(n), because each step iterates through the array at most a constant number of times.
O(1), because the algorithm uses constant extra space.