class Solution:
def firstMissingPositive(self, nums):
n = len(nums)
for i in range(n):
while 1 <= nums[i] <= n and nums[nums[i] - 1] != nums[i]:
nums[nums[i] - 1], nums[i] = nums[i], nums[nums[i] - 1]
for i in range(n):
if nums[i] != i + 1:
return i + 1
return n + 1
class Solution {
public:
int firstMissingPositive(vector<int>& nums) {
int n = nums.size();
for (int i = 0; i < n; ++i) {
while (nums[i] > 0 && nums[i] <= n && nums[nums[i] - 1] != nums[i]) {
swap(nums[i], nums[nums[i] - 1]);
}
}
for (int 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; i++) {
while (nums[i] > 0 && nums[i] <= n && nums[nums[i] - 1] != nums[i]) {
int temp = nums[nums[i] - 1];
nums[nums[i] - 1] = nums[i];
nums[i] = temp;
}
}
for (int i = 0; i < n; i++) {
if (nums[i] != i + 1)
return i + 1;
}
return n + 1;
}
}
var firstMissingPositive = function(nums) {
let n = nums.length;
for (let i = 0; i < n; i++) {
while (nums[i] > 0 && nums[i] <= n && nums[nums[i] - 1] !== nums[i]) {
let temp = nums[nums[i] - 1];
nums[nums[i] - 1] = nums[i];
nums[i] = temp;
}
}
for (let i = 0; i < n; i++) {
if (nums[i] !== i + 1)
return i + 1;
}
return n + 1;
};
You are given an unsorted integer array called nums
. The task is to find the smallest missing positive integer from this array. The solution must run in linear time (O(n)
) and use constant extra space (O(1)
).
n
.
For example, given nums = [3, 4, -1, 1]
, the answer is 2
because 1
is present, 2
is missing, and 3
, 4
are present.
At first glance, you might think to sort the array or use a hash set to keep track of which positive numbers are present. However, sorting is O(n log n)
and using a hash set requires extra space, both of which violate the problem's constraints.
The brute-force way would be to check for 1
, then 2
, then 3
, and so on, but this is inefficient and doesn't meet the time complexity requirement.
The key insight is that the smallest missing positive number must be between 1
and n+1
(where n
is the array's length). If all numbers from 1
to n
are present, then the missing number is n+1
.
The challenge is to find this missing number without extra space and in one pass. This leads to the idea of rearranging the array so that each positive integer x
(where 1 <= x <= n
) is placed at index x-1
.
To solve the problem efficiently, we use the input array itself as a kind of "hash map". The idea is to place each number x
(where 1 <= x <= n
) at position x-1
. Here's how:
i
, if nums[i]
is in the range 1
to n
and not already in its correct position (nums[nums[i] - 1] != nums[i]
), swap it with the element at its target position (nums[nums[i] - 1]
).
i
where nums[i] != i + 1
means i + 1
is missing.
1
to n
are present, then the answer is n + 1
.
This method works because every positive integer that can be placed in the array will be moved to its correct index. The rest (negatives, zeros, duplicates, or numbers > n) are ignored.
Let's use nums = [3, 4, -1, 1]
as an example.
The answer is 2
.
O(n^2)
(for each positive integer, scan the array)O(1)
(no extra data structures)O(n)
. Each number is swapped at most once, so the total number of operations is linear.O(1)
. All operations are done in-place, with no extra storage proportional to n
.The problem asks for the smallest missing positive integer in an unsorted array, with strict time and space constraints. The elegant solution leverages in-place swapping to position each number at its "home" index. This approach efficiently transforms the input so that a single scan reveals the answer. The key insight is recognizing the relationship between values and their ideal indices, allowing us to avoid extra space and meet the linear time requirement.