news 2026/10/29 21:50:20

Bitwise AND of Numbers Range - 题解与思路

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Bitwise AND of Numbers Range - 题解与思路

题目链接:Bitwise AND of Numbers Rangeleetcode​

题目与直觉理解
题目:给定两个整数 left 和 right,表示闭区间 [left, right],返回区间内所有整数的按位与结果。leetcode​
约束:0 <= left <= right <= 2^31 - 1,也就是 32 位非负整数范围。leetcode​
直觉上,如果区间很大(比如从 1 到一个非常大的数),那么某些二进制位在中间某个数上一定会变成 0,最后按位与结果也会在这些位上变成 0。唯一可能保持为 1 的,只能是整个区间里从头到尾都从未变化过的那部分"高位前缀"。

初始错误思路:只看"最高位 1"
一开始容易想到的一个思路是:
把每个数都看成 32 位整数,找"最高位的 1 在哪一位"。
如果区间内所有数的最高位 1 都在同一位,就认为结果是"只有这一位是 1,其余位为 0";否则返回 0。
这个思路抓住了"高位"这个感觉,但有两个致命问题:
只看"最高位是否一致",忽略了"更低位可能也一直为 1"。例如区间 [6, 7]:
6 = 110,7 = 111,最高位 1 都在同一位,但真实结果是 110 (6),而不是 100 (4)。
没有真正找到"公共前缀"的全部部分,等于只保留了最左边那一位。
这说明:我们需要的不是"最高位",而是 left 和 right 的完整"二进制公共前缀"。

正确核心:找二进制公共前缀
这道题有一个非常典型的结论:
区间 [left, right] 所有数的按位与结果,就是 left 和 right 在二进制下的 公共前缀,其余低位全部变为 0。leetcode​
原因可以这样理解:
从 left 增加到 right 的过程中,只要某一位在这个过程中经历过从 0 变 1 或从 1 变 0 的变化,那么这一位在某个数上必然是 0,按位与之后这个位就会变 0。
只有在 left 和 right 对应位完全一致、且在整个区间内不发生变化的那一段"高位前缀",才能在结果中保持为 1。
所以问题变成:如何高效地求出 left 和 right 的公共前缀?

经典解法:不断右移,直到相等
一种常见且优雅的做法是:
用一个计数 shift = 0 记录右移的次数。
当 left < right 时,同时右移 left 和 right 一位(left >>= 1; right >>= 1;),并让 shift++。
循环直到 left == right。此时的 left(或 right)就是它们的公共前缀。
最后将这个公共前缀左移 shift 位,把低位补回 0:left << shift,即为答案。leetcode​
示意伪代码(C 风格):
cpp
int rangeBitwiseAnd(int left, int right) {
int shift = 0;
while (left < right) {
left >>= 1;
right >>= 1;
++shift;
}
return left << shift;
}

这里用 while (left < right) 和 while (left != right) 在题目保证 left <= right 的前提下是等价的,选择哪个更多是风格问题。

为什么右移有效:从"丢掉一定为 0 的尾部"看
每次右移一位,在本质上是在做:丢掉当前的最低位。
当某一位开始在 left 与 right 之间发生差异时,说明在区间 [left, right] 内,这一位必然经历了 0/1 的变化。
因为按位与对所有数都要是 1 才能为 1,一旦某一位在区间里出现过 0,最终结果这位一定是 0。
所以,只要 left < right,说明仍有某些低位是不稳定的(在中间会变化),这些低位我们干脆整体右移"扔掉"。
当右移到 left == right 的那一刻,说明剩下的所有位在整个区间内已经完全一致,它们就是公共前缀。
最后再通过左移 shift 位,把这些高位放回原来的位置,低位补 0,得到最终按位与结果。

细节问题:while 条件与移位方向
关于你在过程中的几个思考点,顺便也整理一下:
left != right 还是 left < right?
题目保证 left <= right,输入不会出现 left > right。leetcode​
又因为每一步都同时右移 left 和 right,不会人为制造 left > right 的情况。
所以 while (left < right) 和 while (left != right) 在这题上效果等价,用哪一个主要看你觉得哪一种更清晰。
算术右移还是逻辑右移?
左移只有一个操作符 <<,没有算术/逻辑之分。
右移在 C/C++/Java 中,>> 对有符号整数通常是"算术右移",保留符号位;Java 还有 >>> 是逻辑右移。
本题保证 0 <= left, right <= 2^31 - 1,全部是非负数,即最高位为 0,不会出现符号扩展问题,所以用 >> 即可,算术右移和逻辑右移在这里表现一致。leetcode​
left == 0 需要特判吗?
不需要。left == 0 时,区间 [0, right] 一定包含 0,整个区间按位与结果必然为 0。
在上面的循环中:
left 右移始终为 0。
right 不断右移直到也变为 0,此时 left == right == 0。
最终返回 0 << shift,仍然是 0,符合预期,无需额外分支。

示例推演:验证思路
以几个典型例子推一遍这个过程,可以更有信心:
left = 6 (110),right = 7 (111):
第一次:left = 3 (11),right = 3 (11),shift = 1。
循环结束,返回 3 << 1 = 110 (6),与真实按位与结果一致。
left = 12 (1100),right = 15 (1111):
第一次:1100 -> 110,1111 -> 111,shift = 1。
第二次:110 -> 11,111 -> 11,shift = 2。
返回 3 << 2 = 1100 (12),与逐个按位与的结果一致。
left = 1,right = 2147483647:
不断右移后,最终两者都会变成 0,shift 为 31。
返回 0 << 31 = 0,符合题目示例。

总结:适合写成博客的结构建议
如果写成一篇博客,大致可以按下面结构组织:
题目描述与样例
直观思路:为什么要找公共前缀
错误/不完整思路:只看最高位 1 的陷阱
正确解法一:右移找公共前缀(你现在实现的解法)
思路描述
代码实现
示例推演
边界条件讨论(left == 0、移位类型等)
复杂度分析:时间 O(logN),空间 O(1)
小结:这类题的共性——“范围按位运算"往往等价于"端点的公共前缀”
https://leetcode.com/problems/bitwise-and-of-numbers-range/?envType=study-plan-v2&envId=top-interview-150
https://leetcode.com/problems/bitwise-and-of-numbers-range/submissions/1876552823/?envType=study-plan-v2&envId=top-interview-150

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/24 6:55:35

dy x-tt-session-dtrait 逆向分析

声明 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由 此产生的一切后果均与作者无关&#xff01; 部分pyhon代码 url "aweme/v1…

作者头像 李华
网站建设 2026/10/28 6:01:03

mysql的存储引擎

关于 MySQL 插件式的存储引擎啊&#xff0c;这个插件式的存储引擎也让它非常灵活的能在不同的具体的业务场景来选择对应的存储引擎&#xff0c;使得它的性能也是非常的灵活强大。我介绍一下我知道的就是经常被对比的的存储引擎是什么&#xff1f; myisam、 Innodb 跟 memory&am…

作者头像 李华
网站建设 2026/10/22 13:43:13

基于java的SpringBoot/SSM+Vue+uniapp的无人机飞行数据管理平台的详细设计和实现(源码+lw+部署文档+讲解等)

文章目录前言详细视频演示具体实现截图技术栈后端框架SpringBoot前端框架Vue持久层框架MyBaitsPlus系统测试系统测试目的系统功能测试系统测试结论为什么选择我代码参考数据库参考源码获取前言 &#x1f31e;博主介绍&#xff1a;✌全网粉丝15W,CSDN特邀作者、211毕业、高级全…

作者头像 李华
网站建设 2026/10/27 5:07:01

缓冲技术与 Spooling 技术是操作系统中实现高效 I/O 管理的关键手段

缓冲技术与 Spooling 技术是操作系统中实现高效 I/O 管理的关键手段。它们通过不同的机制解决 CPU 与外设之间的速度差异和资源独占问题&#xff0c;从而提升系统整体性能。 1. 缓冲技术 作用&#xff1a;缓解 CPU 与 I/O 设备间的速度不匹配&#xff0c;提高设备利用率和系统并…

作者头像 李华
网站建设 2026/10/30 3:15:53

国产 DM 数据库技术学习心得与实践探索

目录一、学习背景与整体认知1.1 国产数据库发展现状1.2 DM 数据库核心定位与技术架构1.3 学习目标与核心收获二、DM 数据库核心技术深度剖析2.1 存储引擎底层原理2.1.1 数据存储结构&#xff08;页、区、段&#xff09;2.1.2 事务日志与恢复机制2.2 SQL 引擎与优化器2.2.1 执行…

作者头像 李华