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

1.题目

题目地址(448. 找到所有数组中消失的数字 - 力扣(LeetCode))

https://leetcode.cn/problems/find-all-numbers-disappeared-in-an-array/

题目描述

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

2.题解

2.1 哈希表

思路

哈希表存储所有出现过的数即可

代码

  • 语言支持:C++

C++ Code:


class Solution {
public:
    vector<int> findDisappearedNumbers(vector<int>& nums) {
        int n = nums.size();
        unordered_map<int, int> mp;
        for(int num: nums){
            if(mp.count(num)){
                mp[num]++;
            } else{
                mp.emplace(num, 1);
            }
        }

        vector<int> ans;
        for(int i = 1; i <= n; i++){
            if(!mp.count(i)){
                ans.push_back(i);
            }
        }
        return ans;
    }
};

复杂度分析

令 n 为数组长度。

  • 时间复杂度:O(n)
  • 空间复杂度:O(n)

2.2 标记法(%循环)

思路

我们希望使空间复杂度降低为O(1),应该如何实现呢?(最后用于返回结果的那个数组不算在内!)

这里比如像某个1-n的数出现了, 我们可以另外用一个数组,一个哈希表来存储他的出现信息;
那我们是否能使用原数组nums来存储出现过数组的信息呢?
注意到数组下标在0-(n-1)中浮动,而数的值为 1-n, 那我们可不可以用数组下标记录所有出现过的值呢?该使用什么标记呢?
我们这里考虑到所有出现的数都在1-n, 如果某个数 i 出现了, 那我们就令nums[i-1] += n, 使其超出n(进行了标记), i-1是因为数和下标差值为1

为何如此标记呢? 因为我们后面还需要用到 nums[i]的值, 就需要还原它, 如何还原呢?
对于所有nums[i] ∈ [1,n], 如果有被标记的数,也就是多了一个n; 如果理解为绕圈,也就是多绕了一圈回来, 对于绕圈问题, 我们直接 % n 即可解决
这也是我们为何选择 + n 而不是选择加其他值的原因.

如何判断是否被标记了呢?
在下一次遍历数组时,找到所有值 <= n 的nums[i]即可, 对应的数即为 下标 + 1 = i + 1

代码

class Solution {
public:
    vector<int> findDisappearedNumbers(vector<int>& nums) {
        int n = nums.size();
        for(int i = 0; i < n; i++){
            int x = (nums[i] - 1) % n;
            nums[x] += n; // 用索引0-(n-1)存储出现过的1-n的数, 差值为1
        }

        vector<int> ans;
        for(int i = 0; i < n; i++){
            if(nums[i] <= n && nums[i] >= 1){
                ans.push_back(i + 1); // 索引和实际值差1 
            }
        }
        return ans;
    }
};

复杂度分析

令 n 为数组长度。

  • 时间复杂度:O(n)
  • 空间复杂度:O(n)
posted @   DawnTraveler  阅读(46)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示