面试题 17.19.消失的两个数字 ---- 位运算

题目链接

题目:

分析:

  • 之前我们做过一道类似的题目: <消失的一个数字>, 我们用的办法是用数组中的每个数字与带上消失的数字的数组中的数字进行^, 这样就得到了消失的数字
  • 但是我们这道题目, 如果按照上述方法, 得到的是两个数字a和b的^, 那么我们怎么将两个数字分开呢?
  • 其实后面就是<只出现一次数字III>的思路:
  • 对于异或后的结果, 如果某一bit位上是1, 说明这两个数字肯定是不同的, 因为^的规则是相同为0,相异为1
  • 那么我们可以根据这个特性, 将我们上述异或在一起的所有数字进行分组, 这一位bit位上为1的是一组, 为0的是一组, 那么每一组中, 一定是一个数字出现一次和其他数字出现两次的情况, 那么我们对每一组在进行异或, 就得到了这两个数字

总结分为以下三步:

  1. 将所有的数异或在一起
  2. 找到tmp上bit位为1的那一位x
  3. 根据x位的不同, 或分成两组分别异或

代码:

java 复制代码
class Solution {
    public int[] missingTwo(int[] nums) {
//1
        int tmp = 0;
        for (int x : nums) {
            tmp ^= x;
        }
        for (int i = 1; i <= nums.length + 2; i++) {
            tmp ^= i;
        }
//2
        int diff = 0;
        while (true) {
            if (((tmp >> diff) & 1) == 1)
                break;
            else
                diff++;
        }
//3
        int[] ret = new int[2];
        for (int x : nums) {
            if (((x >> diff) & 1) == 1) {
                ret[1] ^= x;
            } else {
                ret[0] ^= x;
            }
        }
        for (int i = 1; i <= nums.length + 2; i++) {
            if (((i >> diff) & 1) == 1) {
                ret[1] ^= i;
            } else {
                ret[0] ^= i;
            }
        }
        return ret;
    }
}
相关推荐
爱喝矿泉水的猛男2 小时前
非定长滑动窗口(持续更新)
算法·leetcode·职场和发展
YuTaoShao2 小时前
【LeetCode 热题 100】131. 分割回文串——回溯
java·算法·leetcode·深度优先
源码_V_saaskw3 小时前
JAVA图文短视频交友+自营商城系统源码支持小程序+Android+IOS+H5
java·微信小程序·小程序·uni-app·音视频·交友
超浪的晨3 小时前
Java UDP 通信详解:从基础到实战,彻底掌握无连接网络编程
java·开发语言·后端·学习·个人开发
YouQian7723 小时前
Traffic Lights set的使用
算法
双力臂4044 小时前
Spring Boot 单元测试进阶:JUnit5 + Mock测试与切片测试实战及覆盖率报告生成
java·spring boot·后端·单元测试
Edingbrugh.南空4 小时前
Aerospike与Redis深度对比:从架构到性能的全方位解析
java·开发语言·spring
go54631584654 小时前
基于深度学习的食管癌右喉返神经旁淋巴结预测系统研究
图像处理·人工智能·深度学习·神经网络·算法
QQ_4376643145 小时前
C++11 右值引用 Lambda 表达式
java·开发语言·c++
永卿0015 小时前
设计模式-迭代器模式
java·设计模式·迭代器模式