448. 找到所有数组中消失的数字 - 力扣(LeetCode)
数组重复元素系列:
leetcode 第 645 题:错误的集合(C++)_zj-CSDN博客
剑指 Offer 03. 数组中重复的数字_zj-CSDN博客
LeetCode第 26 题:删除排序数组中的重复项(C++)_zj-CSDN博客
LeetCode第 219 题:存在重复元素 II(C++)_zj-CSDN博客
LeetCode第 217 题:存在重复元素(C++)_zj-CSDN博客
LeetCode第 27 题:移除元素(C++)_zj-CSDN博客
LeetCode第 283 题:移动零(C++)_zj-CSDN博客
LeetCode第 136 题:只出现一次的数字(C++)_zj-CSDN博客
LeetCode第 137 题:只出现一次的数字II(C++)_zj-CSDN博客
LeetCode第 260 题:只出现一次的数字 III(C++)_zj-CSDN博客
如果不作空间要求,使用哈希表很简单。
不适用额外空间,排序+二分:
class Solution {
public:
vector<int> findDisappearedNumbers(vector<int>& nums) {
sort(nums.begin(), nums.end());
int n = nums.size();
vector<int> res;
for(int i = 1; i <= n; ++i){
if(!binary_search(nums.begin(), nums.end(), i)) res.push_back(i);
}
return res;
}
};
能过,但是效率很低。
换个思路:leetcode 第 645 题:错误的集合(C++)_zj-CSDN博客最后一种原地置换的思路,把每个元素都放到正确的位置(和下标对应起来)上去,最后那些下标值和元素值无法对应的,就对应缺失元素:
class Solution {
public:
vector<int> findDisappearedNumbers(vector<int>& nums) {
int n = nums.size();
vector<int> res;
for(int i = 0; i < n; ++i){
while(nums[i] != i+1){
if(nums[i] == nums[nums[i]-1])
break;
swap(nums[i], nums[nums[i]-1]);
}
}
for(int i = 0; i < n; ++i){//最后还不匹配的,就是没出现过的元素
if(nums[i] != i+1) res.push_back(i+1);
}
return res;
}
};
那么同样的道理,leetcode 第 645 题:错误的集合(C++)_zj-CSDN博客的倒数第二种思路也是可行的:
将所有数组值(正数)作为数组下标,置对应下标的值为负值。那么,最后仍为正数的位置即为(未出现过)消失的数字。
class Solution {
public:
vector<int> findDisappearedNumbers(vector<int>& nums) {
int n = nums.size();
vector<int> res;
for(int i = 0; i < n; ++i){
if(nums[abs(nums[i])-1] > 0) nums[abs(nums[i])-1] *= -1;
}
for(int i = 0; i < n; ++i){//最后还不匹配的,就是没出现过的元素
if(nums[i] > 0) res.push_back(i+1);
}
return res;
}
};