题目
给你一个含 个整数的数组
,其中
在区间
内。请你找出所有在
范围内但没有出现在
中的数字,并以数组的形式返回结果。
示例 1:
输入:nums = [4,3,2,7,8,2,3,1] 输出:[5,6]
示例 2:
输入:nums = [1,1] 输出:[2]
解题思路:原地修改
用一个哈希表记录数组 中的数字,再利用哈希表检查
中的每一个数是否出现,从而找到缺失的数。
由于数字范围均在 中,我们也可以用一个长度为
的数组来代替哈希表。这一空间复杂度是
。我们的目标是优化空间复杂度到
。
备注:注意到 的长度恰好也为
,能否让
充当哈希表呢 ?
由于
的数字范围均在
中,我们可以利用这一范围之外的数字,来表达「是否存在」的含义。
具体来说,遍历 ,每遇到一个数
,就让
增加
。由于
中所有数均在
中,增加以后,这些数必然大于
。最后我们遍历
,若
未大于
,就说明没有遇到过数
。这样我们就找到了缺失的数字。
注意,当我们遍历到某个位置时,其中的数可能已经被增加过,故需要对 取模来还原出它本来的值。
复杂度分析
时间复杂度:,其中
是数组
的长度。
空间复杂度:
官方代码
class Solution {
public List<Integer> findDisappearedNumbers(int[] nums) {
int n = nums.length;
//0.遍历标记
for (int num : nums) {
//1.取余取真值
int x = (num - 1) % n;
//2.利用下标+n标记
nums[x] += n;
}
List<Integer> ret = new ArrayList<Integer>();
for (int i = 0; i < n; i++) {
if (nums[i] <= n) {
ret.add(i + 1);
}
}
return ret;
}
}