题目描述:
给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数。
进阶:你可以实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案吗?
示例 1:
输入:nums = [1,2,0]
输出:3
示例 2:
输入:nums = [3,4,-1,1]
输出:2
示例 3:
输入:nums = [7,8,9,11,12]
输出:1
思路分析:
我们将数组中的数放到它们对应的位置上,比如数字 k 就放在第 k - 1 个位置(因为数组下标从 0 开始)。经过这样处理后,如果数组中某个位置上的数不是该位置加 1,那么该位置加 1 的值就是我们要求的最小的未出现的正整数。例如,假设当前位置为 i,它应该存放数字 k,但是数字 k 存储在 j 位置上,那么我们将位置 i 上的数字和位置 j 上的数字交换,这样数字 k 就被放在了该放的位置上,我们可以继续处理位置 i 上的数字。
时间复杂度:O(n),其中 n 是数组的长度。
空间复杂度:O(1)。
Python代码实现:
class Solution(object):
def firstMissingPositive(self, nums):
ls = len(nums)
index = 0
while index < ls:
if nums[index] <= 0 or nums[index] > ls or nums[nums[index] - 1] == nums[index]:
index += 1
else:
pos = nums[index] - 1
nums[index], nums[pos] = nums[pos], nums[index]
res = 0
while res < ls and nums[res] == res + 1:
res += 1
return res + 1
Java代码实现:
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]) {
swap(nums, i, nums[i] - 1);
}
}
for (int i = 0; i < n; ++i) {
if (nums[i] != i + 1) {
return i + 1;
}
}
return n + 1;
}
public void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
C++代码实现:
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;
}
void swap(int &a, int &b)
{
int temp = a;
a = b;
b = temp;
}
};