Find All Numbers Disappeared in an Array
题目
Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once.
Find all the elements of [1, n] inclusive that do not appear in this array.
Could you do it without extra space and in O(n) runtime? You may assume the returned list does not count as extra space.
Example:
Input:
[4,3,2,7,8,2,3,1]
Output:
[5,6]
解决
1. bool数组
利用bool数组记录数是否出现。若bool[i]
值为false
,证明该数i
不存在;若bool[i]
值为true
,证明该数i
存在。
时间复杂度为O(n)
(因为只需遍历数组和bool数组各一遍)
空间复杂度为O(n)
(因为需要开一个大小为n
的bool数组)。
class Solution {
public:
vector<int> findDisappearedNumbers(vector<int>& nums) {
vector<int> result;
int num = nums.size();
bool exist[num + 1] = {false}; // 初始化为都不存在
for (int i = 0; i < num; i++) {
exist[nums[i]] = true;
}
for (int i = 1; i < num + 1; i++) {
if (!exist[i]) result.push_back(i);
}
return result;
}
};
2. 不利用额外的空间
这种方法是不利用额外的空间,原有的空间进行判断。将出现的数作为下标,使该下标对应的数变为负数。
若abs(array[i]) == temp
(预防之前的操作将array[i]
变为负数):
- 若
array[temp - 1] > 0
,则表明此时temp
是第一次出现,将array[temp - 1]
置为相反数。 - 若
array[temp - 1] < 0
,则表明此时temp
在之前已经出现过了,不作任何处理。
PS:注意的是,数组下标是从0
开始的。
时间复杂度为O(n)
(因为需要遍历数组一遍)
空间复杂度为O(1)
(没有用额外的空间)。
class Solution {
public:
vector<int> findDisappearedNumbers(vector<int>& nums) {
vector<int> result;
int num = nums.size();
for (int i = 0; i < num; i++) {
int temp = abs(nums[i]);
if (nums[temp - 1] > 0) {
nums[temp - 1] = 0 - nums[temp - 1];
}
}
for (int i = 0; i < num; i++) {
if (nums[i] > 0) {
result.push_back(i + 1);
}
}
return result;
}
};