缺失的第一个正数
前置算法: 复原数组
先看一个基础算法, 快速复原一个无序数组, 使得nums[i] == i
, 且数组中的元素都是从0开始的有序数
比如数组长度为5,那么数组中的元素就是0 1 2 3 4
,且不重复
要恢复这个数组,使得num[i] == i
, 就是使用交换,代码如下
void reset(vector<int>& nums)
{
for(int i = 0; i < nums.size(); i++)
while(nums[i] != i)
swap(nums[i], nums[nums[i]]);
}
这样运行一遍,所有位置的数字就都会满足num[i] == i
算法
当前问题和复原数组问题很相似,
首先正整数从1开始,所以所有元素需要减1,
其次,如果原数组恰好是从1开始的正整数数组,那么每个元素i
就应该能交换回nums[i]
位置
所以算法就是,
- 对处在区间内的元素进行交换,反之跳出
- 之后从前往后遍历一遍,如果
i != nums[i]
,那么i + 1
就是结果
class Solution {
public:
int firstMissingPositive(vector<int>& nums) {
for(auto &x : nums)
if(x != INT_MIN) --x;
int n = nums.size();
for(int i = 0; i < nums.size(); i++)
{
while(nums[i] >= 0 && nums[i] < n && nums[i] != i && nums[i] != nums[nums[i]])
swap(nums[i], nums[nums[i]]);
}
for(int i = 0; i < n; i++)
if(nums[i] != i) return i + 1;
return n + 1;
}
};