leetcode448 找到所有数组中消失的数字

leetcode448 找到所有数组中消失的数字

对于这道题目,我们进行分析,题目的特点在于首先数组内数字的大小是小于等于数组大小的,意味着我们可以通过数组的大小来判断数组内数字的大小
思路1

  • 我们先构建一个大小为nums.size()的数组,用来作为我们的统计表
  • 然后遍历原数组,对于原数组中数字出现次数进行统计
 		 vector<int> ret(nums.size(), 0);
         for(int i = 0; i < nums.size(); i++)
         {
             ret[nums[i] - 1]++;
         }
  • 在得到我们已统计好的数组中,我们只需要查找数组中哪个数字为0就可以找到消失的数字了
    该方法需要借助额外的数组
    空间复杂度 O(n)
    时间复杂度 O(n)

思路2

我们进一步考虑原地哈希,由于数组内的数字范围是确定的,那么我们能否通过交换的思想让数组中出现数字的正确位置加上n, n为数组大小

举例说明
[4,3,2,7,8,2,3,1]
按照我们的思想,对于数组中出现数字的正确位置
对于4而言他本来正确位置是nums[3],因此我们对nums[3]的数字加上n
更新后的数组为
[4,3,2,15,8,2,3,1]
对3处理后
更新后的数组
[4,3,10,15,8,2,3,1]
在对2进行处理的时候,我们发现原来2的位置已经被10替换,如果我们依然去寻找nums[10]的位置的话们就会发生数组越界
这里就体现了我们为什么加上的是n而不是任意一个数,我们想要让数组内的数字全都能落到[0–n-1]的区间,则需要进行(%)取余处理,这样数组内的所有数都可以映射到[0 — n-1],需要注意的是我们在进行取余的操作是

int x = (nums[i]-1) % size;

注意是nums[i - 1]% size

所以对数组[4,3,10,15,8,2,3,1]处理的结果为
[4,11,10,15,8,2,3,1]
通过这样处理,最终就可以在筛选出消失的数字了,因为消失数字的位置是没经过+n操作的,我们只需要遍历数组寻找小于等于size的位置就可以

class Solution {
public:
    vector<int> findDisappearedNumbers(vector<int>& nums) {
        //利用原有原数组使用哈希技巧
        //code2 实现原地修改
        //就在该数组的基础上 对于该数组进行处理,对于数组内每个数组,都在[1, N]的范围内,
        //为了方便理解 我们去数组[1,2,2]
        //我们对数组内的值让其加上n 对于数子1 它本该出现在下标为0的位置 所以我们让下标为0 的数据+n代表该位置数据已经出现过 对于缺少的3而言 由于数组中没有出现3 所以经过一轮转换之后 该位置数字会小于n 
        int size  = nums.size();
        for(int i = 0; i < size; ++i)
        {
            //存在数据有可能已经被处理过情况
            //需要先对数据进行取余处理
            int x = (nums[i]-1) % size;
            nums[x] += size;
        }
        vector<int> ret;
        for(int i = 0; i < size; ++i)
        {
            if(nums[i] <= size)
            {
                ret.push_back(i+1);
            }
        }
        return ret;
    }
};

该方法无需借助额外的数组
空间复杂度 O(1)
时间复杂度 O(n)
leetcode448 找到所有数组中消失的数字

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值