题目大意:大小为n的数组中,每个数满足1≤a[i]≤n,有些元素出现了两次,这意味着1~n中有些数字没有出现在数组中,找到这些数字。要求时间复杂度O(n),空间复杂度O(1)。
分析:由于要求不使用额外空间,所以需要利用好数组内元素取值范围这个特点。由于数组内元素值在1~n之间,所以可以利用元素值对应的下标做标记,来记录哪些值是出现过的。
第一步:遍历数组,遍历时将nums[abs(nums[i])-1]标记为负数(也就意味着abs(nums[i])出现过),如果nums[abs(nums[i])-1]已经为负(已经标记过),那就不用再标记了。
第二步:遍历数组,遍历时判断nums[i]正负,如果为正,就说明该位置没有被标记过,也就是(i+1)这个数没有出现过
代码:
class Solution {
public:
vector<int> findDisappearedNumbers(vector<int>& nums) {
vector<int> ans;
for(int i = 0;i < nums.size();i++){
if(nums[abs(nums[i]) - 1] > 0)
nums[abs(nums[i]) - 1] *= (-1);
}
for(int i = 0;i < nums.size();i++){
if(nums[i] > 0) ans.push_back(i + 1);
}
return ans;
}
};