LeetCode-448. 找到所有数组中消失的数字

题目来源

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) 的情况下解决这个问题吗? 你可以假定返回的数组不算在额外空间内。

题解分析

解法一:鸽笼原理

  1. 本题如果没有对空间复杂度的原地要求,其实是可以使用HashMap来完成的,或者也可以使用另一个数组来完成没有出现元素的判断。
  2. 考虑到本题的数组比较特殊,它的长度是n,而数组里的所有元素大小都在1-n之间。那我们可以想,是否可以就使用当前数组来做筛选呢?
  3. 答案是可以的,当遍历一个元素num时,我们可以把第num位置标记一下。不过,我们应该为第num个位置放置什么元素呢?肯定不能随便放置,因为这个元素有可能还没有遍历到,不能随意改变原有的值。
  4. 其实,我们可以利用取模的思想,将一个元素加上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;
    }
}

结果展示

image

posted @ 2022-01-19 11:39  Garrett_Wale  阅读(43)  评论(0编辑  收藏  举报