LeetCode-448. 找到所有数组中消失的数字
题目来源
题目详情
给你一个含 n
个整数的数组 nums
,其中 nums[i]
在区间 [1, n]
内。请你找出所有在 [1, n]
范围内但没有出现在 nums
中的数字,并以数组的形式返回结果。
示例 1:
输入: nums = [4,3,2,7,8,2,3,1]
输出: [5,6]
示例 2:
输入: nums = [1,1]
输出: [2]
提示:
n == nums.length
1 <= n <= 105
1 <= nums[i] <= n
进阶: 你能在不使用额外空间且时间复杂度为 O(n)
的情况下解决这个问题吗? 你可以假定返回的数组不算在额外空间内。
题解分析
解法一:鸽笼原理
- 本题如果没有对空间复杂度的原地要求,其实是可以使用HashMap来完成的,或者也可以使用另一个数组来完成没有出现元素的判断。
- 考虑到本题的数组比较特殊,它的长度是n,而数组里的所有元素大小都在1-n之间。那我们可以想,是否可以就使用当前数组来做筛选呢?
- 答案是可以的,当遍历一个元素num时,我们可以把第num位置标记一下。不过,我们应该为第num个位置放置什么元素呢?肯定不能随便放置,因为这个元素有可能还没有遍历到,不能随意改变原有的值。
- 其实,我们可以利用取模的思想,将一个元素加上n后再对n取模结果是不变的,而且通过加n也可以用来判断第num个位置是否已经考虑过了,换句话说就是值为num的元素是否出现在原数组中。
class Solution {
public List<Integer> findDisappearedNumbers(int[] nums) {
int n = nums.length;
for(int num : nums){
int index = (num - 1) % n;// num在1-n之内
nums[index] += n;
}
List<Integer> list = new ArrayList<>();
for(int i =0; i<n; i++){
int num = nums[i];
if(num <= n){
list.add(i+1);
}
}
return list;
}
}
结果展示
Either Excellent or Rusty