1. 这题其实没有想象中的那么难,关键得利用数组的特性,我们得将不在正确位置的数放在对应的正确的位置上,然后再遍历,得到不满足条件的那个数,即为缺失的那个数.
2. 卡了好长时间是因为这个交换两个数需要特别注意,顺序错了不行,因为交换的数的索引含有nums[i],即为nums[nums[i]-1],因此顺序一点不能错,这也是最需要注意的地方.
class Solution {
public:
int firstMissingPositive(vector<int>& nums) {
//边界条件
if(nums.size()==0) return 1;
for(int i=0;i<nums.size();) {
//只有当数不在范围内,或者对应的数在正确的位置,才不需要做任何改变.
//也只有此时才能i++,因为下面交换过的数有可能还是不在正确的位置,
//所以一直到满足if条件才不需要继续交换.
if(nums[i]<=0 || nums[i]>=nums.size()+1 || nums[nums[i]-1]==nums[i]) {
i++;
continue;
}
//不在正确的位置需要交换到正确的位置.
//强烈注意交换的顺序,只能有这么一种方式,
//因为nums[i]也出现在索引中,所以我们只能最后改变
//nums[i]的值才不会影响前面的交换.
int tmp = nums[nums[i]-1];
nums[nums[i]-1] = nums[i];
nums[i] = tmp;
}
//遍历找到不在正确位置的数返回,即为缺失的值.
for(int i=0;i<nums.size();i++) {
if(nums[i]!=i+1) return i+1;
}
//如果都满足,则缺失之后的数.
return nums.size()+1;
}
};