LeetCode笔记:448. Find All Numbers
问题(Easy):
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 ≤ a[i] ≤ n (n = 数组尺寸),有一些元素出现了两次,而其余的只出现一次。
找到[1,n]中所有没在数组中出现的元素。
你能不能不用额外的空间且在O(n)时间下做?你可以假设用于返回的列表不视为额外空间。
例:
输入:
[4,3,2,7,8,2,3,1]
输出:
[5,6]
他山之石:
转换一个思路,我们先遍历一遍数组,因为元素内容都在1~数组长度中,所以我们将元素值对应位置值都设为负数,比如例子中我们将第四个元素、第三个元素、第二个元素等等都设为负数(这里注意元素值要减一才是位置),当然无论一个元素出现几次,我们都保证对应位置的值设为负数。
然后遍历第二次,看哪个位置的值不为负数,这说明没有出现过对应的值,因此将位置加一,就是没出现过的值了。
有一个提升速度的技巧在于遍历时判断遍历条件时,不要每次都去判断 i < nums.size() ,这样每次都要计算一遍数组尺寸,而应该事先计算出一次,保存在一个变量中,每次只去对比这个算出来的变量即可,经过测试这样节省的时间长达69ms!
代码(C++):
class Solution {
public:
vector<int> findDisappearedNumbers(vector<int>& nums) {
vector<int> res;
int len = nums.size();
for (int i = 0; i < len; i++) {
int n = abs(nums[i])-1;
if (nums[n] > 0) nums[n] = -nums[n];
}
for (int i = 0; i < len; i++) {
if (nums[i] > 0) res.push_back(i+1);
}
return res;
}
};
合集:https://github.com/Cloudox/LeetCode-Record