448. 找到所有数组中消失的数字
描述
给你一个含 n 个整数的数组 nums ,其中 nums[i] 在区间 [1, n] 内。请你找出所有在 [1, n] 范围内但没有出现在 nums 中的数字,并以数组的形式返回结果。
链接
448. 找到所有数组中消失的数字 - 力扣(LeetCode) (leetcode-cn.com)
解法:特殊标记(使得空间复杂度为 O(1))
如何利用 nums 作为辅助数组,来记录每个数字是否出现呢?
对于第 i 个数字 nums[i],我们位置 (nums[i] - 1) % n 的位置增加 n,这样不会覆盖原数组,因为 (nums[i] - 1) % n = (nums[i] - 1 + n) % n,这样如果最后遍历完数组,nums[i] 小于等于 n,就是数组中中消失的数字。
下图以示例数据为例,演示了方法二的思路。
1 class Solution { 2 public List<Integer> findDisappearedNumbers(int[] nums) { 3 int n = nums.length; 4 for (int num : nums) { 5 int x = (num - 1) % n; // 对应的 序号 6 nums[x] += n; // 把 有序号的 相加了 一遍 7 } 8 List<Integer> ret = new ArrayList<Integer>(); 9 for (int i = 0; i < n; i++) { 10 if (nums[i] <= n) { 11 ret.add(i + 1); 12 } 13 System.out.println("nums:" + i + "," + nums[i]); 14 } 15 return ret; 16 } 17 }
解法二:哈希表
1 class Solution { 2 public List<Integer> findDisappearedNumbers(int[] nums) { 3 List<Integer> res = new ArrayList<>(); 4 Set<Integer> dic = new HashSet<>(); 5 for(int num : nums) { 6 dic.add(num); 7 } 8 9 for(int i= 1; i <= nums.length; i++) { 10 if(!dic.contains(i)) { 11 res.add(i); 12 } 13 } 14 return res; 15 } 16 }
参考
找到所有数组中消失的数字 - 力扣(LeetCode) (leetcode-cn.com)