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

【算法题】数组中只出现一次的两个数字

数组中只出现一次的两个数字

  • 1. 题目
  • 2. 思路
    • 2.1 哈希表
    • 2.2 位运算

1. 题目

在这里插入图片描述
标签: 哈希表, 位运算.

2. 思路

2.1 哈希表

最简单的方法肯定是用哈希表, 遍历一遍数组找到只出现一次的两个数字. 相关代码就不贴了. 不过这样的话空间复杂度是 O(n), 太高了.

2.2 位运算

另一个想法就是位运算.
我们已知, 两个相同的数字做异或的结果为 0, 如 1001(十进制为9) ⊕ 1001 = 0, 而不同数字异或: 1001 ⊕ 0101 = 1100.
那么显然, 如果数组中存在一个只出现一次的数字, 可以把所有数组元素异或一下求出, 如: 1⊕1⊕3⊕6⊕6⊕5⊕5 = 3.
但问题是现在有两个只出现了一次的数字, 异或下来的结果为: 1⊕1⊕3⊕6⊕6⊕5⊕5⊕4 = 3⊕4 = 0011⊕0100 = 0111(十进制7). 这时候并不能从 0111 中直接拆出 3 和 4 了.
那么接下来的思路就是想办法把 3 和 4 区分开来. 在区分一个数是奇偶数时, 我们通过用 &1 操作, 这里我们也可以用类似的方法, 具体来说, 对于两个数字异或的结果, 从二进制低位开始, 找到第一位为 1 的(也就是原来两个数字中不同的那一位), 用它就可以区分开两个数了.
看个例子更直观一点:
要区分 0100 (4) 和 1100 (6), 我们只需要从二进制的低位到高位依次看, 找到第一位不同的, 在这里就是最高的那位, 记为 1000. 然后用 1000 分别和两个数做 &, 0100 & 1000 = 0000, 1100 & 1000 = 1000, 通过 & 的结果, 一个为0 ,另一个不为0 ,就可以区分开.
那怎么找第一位不同的呢? 别忘了我们之前做过异或, 0100⊕1100 = 1000, 这样就可以从低到高扫描了.
上代码:

public int[] FindNumsAppearOnce (int[] array) {

        // 先将全部数进行异或运算,得出最终结果
        int tmp = 0;
        for(int num: array){
            tmp ^= num;
        }

        // 找到那个可以充当分组去进行与运算的数
        // 从最低位开始找起
        int mask = 1;
        while((tmp&mask) == 0){
            mask <<= 1;
        }

        // 进行分组,分成两组,转换为两组 求出现一次的数字 去求
        int a = 0;
        int b = 0;
        for(int num:array){
            if((num&mask) == 0){
                a ^= num;
            }else{
                b ^= num;
            }
        }
        // 因为题目要求小的数放前面,所以这一做个判断
        if(a > b){
            int c = a;
            a = b;
            b = c;
        }
        return new int[]{a,b};
    }

http://www.kler.cn/news/359393.html

相关文章:

  • 一款基于 Vue 3 的现代化数据可视化组件库,功能强大,颜值爆表,开发者必备!(带私活源码)
  • MATLAB针对模型外表面画出机械臂喷涂轨迹
  • 1.计算机网络_基本知识
  • jenkins添加新服务
  • Vue2的依赖注入(跨级通信)基本使用
  • 【从零开始的LeetCode-算法】945. 使数组唯一的最小增量
  • 五款最佳免费解压软件APP推荐:手机端高效解压工具盘点
  • SHELL脚本之循环语句的for循环以及中断循环的语句
  • 暖水毯/取暖毯语音识别控制芯片IC方案
  • 使用Verilog设计分频模块(2Hz)
  • 外贸商城源码,进出口跨境电商平台电脑端+移动端网站+客服系统 网站设计及源码输出
  • 基于Java+Springboot+Vue开发的体育用品商城管理系统
  • @RequestMapping对不同参数的接收方式
  • Bluetooth Channel Sounding中关于CS Step及Phase Based Ranging相应Mode介绍
  • 算法|牛客网华为机试1-10C++
  • LeetCode第100题:相同的树
  • 10-Python基础编程之函数
  • OpenLayers:构建现代Web地图应用
  • 用动态IP软件改变IP地址:探索原理与实用指南‌
  • CTFHUB技能树之文件上传——前端验证