【面试经典150 | 位运算】数字范围按位与

文章目录

Tag

【位运算】


题目来源

201. 数字范围按位与


题目解读

计算给定区间内所有整数的按位与的结果。


解题思路

本题朴素的方法是直接将区间内的所有整数按位与,时间复杂度为 O ( n ) O(n) O(n),数据量已经达到 1 0 1 0 10^10 1010,必然超时。接下来介绍两种不会超时的方法。

方法一:公共前缀

先来说说什么是公共前缀,公共前缀指的是所有需要按位与计算的数对应的二进制数从高位到低位公共的二进制字符。比如 [9, 12] 的公共前缀为 0000 1,解释如图所示:

根据上图,我们发现连续数字按位与的值等于公共前缀后面再补上剩余的 0。 这个规律正确吗?我们来证明一下。假设对于连续区间内所有数的二进制数,前 i 位(从高位开始数)均相同,第 i+1 位开始不同,由于区间 [m, n] 连续,所以区间内从小到大先枚举出来的数的第 i+1 位为 0,枚举出来相对靠后数的第 i+1 位全部为 1。 并且一定存在连续的两个数 xx+1 满足 x 的第 i+1 位为 0,后面全为 1x+1 的第 i+1 位为 1,后面全为 0,对应上图中的例子即为 1112。这种形如 0111...1000... 的二进制串的按位与的结果一定为 0000...,因此第 i+1 位开始的剩余位均为 0,前 i 位由于均相同,因此按位与结果不变。最后的答案即为二进制字符串的公共前缀再用零补上后面的剩余位。

实现代码

cpp 复制代码
class Solution {
public:
    int rangeBitwiseAnd(int left, int right) {
        int res = 0;
        for (int i = 0; i < 32; ++i) {
            for (int num = left; num <= right; ++num) {
                res |= num & 1;
                num >>= 1;
            }
        }
        return res;
    }
};

复杂度分析

时间复杂度: O ( l o g n ) O(logn) O(logn), n n n 为 right 的值、

空间复杂度: O ( 1 ) O(1) O(1)。

方法二:n & (n-1)

根据方法一,我们知道需要保留的是区间 [m, n] 中的公共前缀,也就是去掉非公共前缀的部分,我们可以使用 n & (n-1) 来去除,直到 m = n,最后返回 n 即可。于是有代码:

实现代码

cpp 复制代码
class Solution {
public:
    int rangeBitwiseAnd(int m, int n) {
        while (m < n) {
            n &= (n-1);
        }
        return n;
    }
};

复杂度分析

时间复杂度: O ( l o g n ) O(logn) O(logn), n n n 为 right 的值、

空间复杂度: O ( 1 ) O(1) O(1)。


写在最后

如果文章内容有任何错误或者您对文章有任何疑问,欢迎私信博主或者在评论区指出 💬💬💬。

如果大家有更优的时间、空间复杂度方法,欢迎评论区交流。

最后,感谢您的阅读,如果感到有所收获的话可以给博主点一个 👍 哦。

相关推荐
珍珠是蚌的眼泪7 天前
LeetCode_位运算
leetcode·位运算·异或·韩明距离·数字的补数
源代码•宸7 天前
Leetcode—2749. 得到整数零需要执行的最少操作数【中等】(__builtin_popcountl)
c++·经验分享·算法·leetcode·位运算
CUC-MenG22 天前
2025杭电多校第十场 Cut Check Bit、Multiple and Factor 个人题解
数学·dp·位运算·数位dp·根号分治
Q741_1471 个月前
如何判断一个数是 2 的幂 / 3 的幂 / 4 的幂 / n 的幂 位运算 总结和思考 每日一题 C++的题解与思路
开发语言·c++·算法·leetcode·位运算·总结思考
CUC-MenG1 个月前
2025牛客多校第五场 K.完美旅程 J.最快覆盖问题 E.神秘异或操作 个人题解
数学·dfs·bfs·优先队列·二分·位运算·fmt·曼哈顿距离·fwt
Tisfy1 个月前
LeetCode 2411.按位或最大的最小子数组长度:一次倒序遍历
数据结构·算法·leetcode·题解·位运算·遍历
老马啸西风2 个月前
java 位运算转换 bit operator convert
java·开发语言·算法·leetcode·面试·力扣·位运算
ゞ 正在缓冲99%…2 个月前
leetcode67.二进制求和
算法·leetcode·位运算
让我们一起加油好吗3 个月前
【基础算法】枚举(普通枚举、二进制枚举)
开发语言·c++·算法·二进制·枚举·位运算
Thanks_ks4 个月前
19 C 语言位运算、赋值、条件、逗号运算符详解:涵盖运算符优先级与复杂表达式计算过程分析
位运算·运算符优先级·赋值运算符·三元运算符·c 语言运算符·逗号运算符·复杂表达式解析