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

【位运算】消失的两个数字(hard)

消失的两个数字(hard)

  • 题⽬描述:
  • 解法(位运算):
  • Java 算法代码:
  • 更简便代码

题⽬链接:⾯试题 17.19. 消失的两个数字

题⽬描述:

给定⼀个数组,包含从 1 到 N 所有的整数,但其中缺了两个数字。你能在 O(N) 时间内只⽤ O(1) 的
空间找到它们吗?
以任意顺序返回这两个数字均可。
⽰例 1:
输⼊: [1]
输出: [2,3]
⽰例 2:
输⼊: [2,3]
输出: [1,4]
提⽰:
nums.length <= 30000

解法(位运算):

算法思路:
本题就是 268. 丢失的数字 + 260. 只出现⼀次的数字 III 组合起来的题。
先将数组中的数和 [1, n + 2] 区间内的所有数「异或」在⼀起,问题就变成了:有两个数出现了「⼀次」,其余所有的数出现了「两次」。进⽽变成了 260. 只出现⼀次的数字 III 这道题。

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. 找出 a,b 两个数⽐特位不同的那⼀位int diff = 0;while(true){if(((tmp >> diff) & 1) == 1) break;else diff++;}// 3. 将所有的数按照 diff 位不同,分两类异或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;}
}

求解方法是利用「异或」+「lowbit」。

由于我们明确了是在 [1,n+2] 中缺失了两个数,我们可以先通过异或 [1,n+2] 以及所有的 nums[i] 来得到缺失两个数值异或和 t。

我们知道异或结果二进制表示为 1 代表了两缺失值该位置数值不同(一个该位置 0,另一个该位置为 1),我们可以根据异或和 t 中任意一位为 1 的位置来将两个缺失值划分到两组中。

更加优雅的方式是使用 lowbit 操作:d = t & -t 可快速得到只保留 t 中最低位 1 的对应数值。

随后将 [1,n+2] 中满足 i & d != 0 的所有 i(含义为对应位置为 1 的数值)与 nums[i] 中满足 nums[i] & d != 0 的所有 nums[i](含义为对应位置为 1 的数值) 进行异或,最终能够确定其中一个缺失值,再结合最开始的异或和 t 即可确定另外一个缺失值。

更简便代码

class Solution {public int[] missingTwo(int[] nums) {// 1. 先把所有的数异或在⼀起int n = nums.length + 2, cur = 0;for (int i = 1; i <= n; i++) cur ^= i;for (int x : nums) cur ^= x;// 2. 找出 a,b 两个数⽐特位不同的那⼀位int t = cur, d = cur & -cur;// 3. 将所有的数按照 diff 位不同,分两类异或cur = 0;for (int i = 1; i <= n; i++) {if ((d & i) != 0) cur ^= i;}for (int x : nums) {if ((d & x) != 0) cur ^= x;}return new int[]{cur, t ^ cur};}
}

时间复杂度:O(n)
空间复杂度:O(1)
注意:
if ((d & i) != 0) cur ^= i;不是if (d & i != 0) cur ^= i;(必须加括号)

http://www.xdnf.cn/news/13292.html

相关文章:

  • websocket实践
  • 通过Netplan为Ubuntu服务器新增DNS以解析内部域名
  • 设计模式-适配器模式
  • 微信小程序 - 手机震动
  • 《P1168 中位数》
  • 期末考试复习总结-《应用程序框架基础》
  • 系统网站首页三种常见布局vue+elementui
  • 【Element Plus】Menu组件:url访问页面时高亮对应菜单栏
  • 板凳-------Mysql cookbook学习 (十--4)
  • 小程序动画性能提升指南:CSS硬件加速与JavaScript动画框架对比
  • CentOS下的运维监控Grafana部署
  • 【HarmonyOS Next之旅】DevEco Studio使用指南(三十二) -> 构建系统生命周期
  • okhttp 实现长连接的完整方案
  • OpenLayers 获取地图状态
  • Docker 安装教程(CentOS 系统)纯新手可入门
  • wordpress后台更新后 前端没变化的解决方法
  • Java异步编程之消息队列疑难问题拆解
  • 2506C++,C++的时间库
  • 搭建本地瓦片地图服务器的完整指南
  • 脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
  • SCAU期末笔记 - 数据分析与数据挖掘题库解析
  • 使用 ML.NET Model Builder 训练机器学习模型进行预测性维护
  • 60天python训练计划----day50
  • 连锁超市冷库节能解决方案:如何实现超市降本增效
  • spring中的ImportSelector接口详解
  • 《高等数学》(同济大学·第7版)第四章第一节不定积分的概念与性质
  • 微软PowerBI考试 PL300-在 Power BI 中设计语义模型 【附练习数据】
  • C++11列表初始化:从入门到精通
  • Python学习(8) ----- Python的类与对象
  • 用 Rust 重写 Linux 内核模块实战:迈向安全内核的新篇章