因为要求时间和空间都要在O(n)内,所以用下标标记每个数是否出现,然后再顺序遍历,输出第一个下标未被标记的数,这种方法是不行的
应该遍历一边数组,判断 nums[nums[i] - 1] != nums[i](下标从0开始),如果不在,则交换num[i]和num[num[i]-1]。
我们的思路是把1放在数组第一个位置nums[0],2放在第二个位置nums[1],即需要把nums[i]放在nums[nums[i] - 1]上,那么我们遍历整个数组,如果nums[i] != i + 1&&nums[i]!=nums[nums[i] - 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;
}
};