当前位置: 首页 > article >正文

Leetcode 寻找重复数

在这里插入图片描述
可以使用 位运算 来解决这道题目。使用位运算的一个核心思想是基于数字的二进制表示,统计每一位上 1 的出现次数,并与期望的出现次数做比较。通过这种方法,可以推断出哪个数字重复。

class Solution {
public:
    int findDuplicate(vector<int>& nums) {
        int n = nums.size() - 1; //这里注意是nums.size()-1,因为size是n + 1,所以数字取值范围是 [1,n]
        int countNum = 0; 
        int expectedNum = 0;
        int result = 0;
        //遍历32位,题目n<=10^5,所以最大数也足够用32位来表示了
        for(int bit = 0; bit < 32; ++bit) {
            //遍历每一位时,首先需要在循环初始将这两个计数器清零。或者在循环末尾处清零。
            countNum = 0;
            expectedNum = 0;
            //设置掩码
            int mask = 1 << bit; //1左移bit位,每左移1次相当于乘2
            
            //然后数组中每个数字和当前mask进行与运算,判断当前位 值为1的数字个数
            for(int num : nums) {
                if(num & mask) {
                    countNum++;
                }
            }
            
            //然后区间[1,n]每个数字与当前mask进行与运算,判断当前位 值为1的数字个数
            for(int i = 1; i <= n; ++i) {
                if(i & mask) {
                    expectedNum++;
                }
            }

            //然后如果当前位的countNum > expectedNum, 说明重复数字在当前位的值为1;
            if(countNum > expectedNum) {
                result = result | mask;
            }
            //countNum = 0;
            //expectedNum = 0;
        }
        return result;
    }
};

解释:

  1. 由于 nums 数组长度是 n + 1,所以它包含从 1 到 n 的数字,且有一个重复数字。
  2. 我们逐位检查每一个 bit(从 0 到 31),统计 nums 数组中哪些数字在该位上是 1,接着统计从 1 到 n 的数字在该位上是 1 的个数。
  3. 如果 nums 中在某个位上的 1 的个数多于从 1 到 n 的数字在该位上的 1 的个数,说明重复的数字在该位上是 1。
  4. 最终通过将这些结果合并(使用按位或运算),我们就能得到重复的数字。

优点:

  • 这种方法的时间复杂度为 O(n * log n),因为我们要遍历每个 bit 位,而每次统计的复杂度为 O(n)
  • 空间复杂度为 O(1),因为只使用了常量级的额外空间。

这是一个比较巧妙的位运算解法,适用于这类寻找重复数的场景。


http://www.kler.cn/a/304296.html

相关文章:

  • 《硬件架构的艺术》笔记(一):亚稳态
  • TCP可靠连接的建立和释放,TCP报文段的格式,UDP简单介绍
  • 【Vue】Vue3.0(二十)Vue 3.0 中mitt的使用示例
  • OpenGL 进阶系列07 - 阴影贴图(shadowmap )
  • ESLint 使用教程(四):ESLint 有哪些执行时机?
  • 从0开始深度学习(25)——多输入多输出通道
  • 提升工作效率:寻找编程工具的秘密武器
  • 使用Docker快速安装和运行Elasticsearch
  • 内蒙古优质农畜产品天津推介会成功举办
  • 【C++学习笔记】逻辑判断语句与循环语句(二)
  • 算法41:位1的个数
  • 赎金信--力扣383
  • 『功能项目』战士的伤害型技能【45】
  • ubuntu安装containerd,取代docker
  • Java面试题——第七篇(Java Web)
  • Redis 篇-深入了解基于 Redis 实现消息队列(比较基于 List 实现消息队列、基于 PubSub 发布订阅模型之间的区别)
  • mfc140u.dll丢失有啥方法能够进行修复?分享几种mfc140u.dll丢失的解决办法
  • 从零实现诗词GPT大模型:实现多头自注意力
  • 灌区信息化发展趋势展望
  • 基于MATLAB的图像融合设计
  • 2024年9月中国数据库排行榜:openGauss系多点开花,根社区优势明显
  • Linux进阶命令-sortwc
  • [Web安全 网络安全]-文件上传漏洞
  • 创建者设计模式
  • 使用 React Testing Library 测试自定义 React Hooks
  • 《自然语言处理 Transformer 模型详解》