给定范围 [m, n],其中 0 <= m <= n <= 2147483647,返回此范围内所有数字的按位与(包含 m, n 两端点)。
示例 1:
输入: [5,7]
输出: 4
示例 2:
输入: [0,1]
输出: 0
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/bitwise-and-of-numbers-range
【解答】
my
public int rangeBitwiseAnd(int m, int n) {
if (m == 0 || n == 0) {
return 0;
}
if (m == n) {
return m;
}
int log = (int)Math.floor(Math.log(m)/Math.log(2))+1;
if(n>=Math.pow(2,log)){
return 0;
}
int res = m;
for (int i = m + 1; i <= n; i++) {
res &= i;
if (i == Integer.MAX_VALUE){
break;
}
}
return res;
}
【位移】
官方:所有数字按位与运算的结果是所有对应二进制字符串的公共前缀再用零补上后面的剩余位
证明:假设对于[m,n]所有二进制串,前 i 位均相同,第 i+1 位开始不同;
由于 [m,n] 连续,所以从小到大的所有二进制串在第i+1位上列举出来一定是前面部分更小的数字是 0,后面部分是 1,所有二进制串按位与的结果一定为 0;
因此第 i+1 位开始的剩余位均为 0,前 i 位由于均相同,因此按位与结果不变。
进一步来说,[m,n]所有二进制字符串的公共前缀就是起始m和结束 n 的公共前缀
Brian Kernighan算法:清除二进制串中最右边的 1(一种右移),n = n & (n - 1)
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/bitwise-and-of-numbers-range/solution/shu-zi-fan-wei-an-wei-yu-by-leetcode-solution/
public int rangeBitwiseAnd(int m, int n) {
if (m == 0 || n == 0) {
return 0;
}
if (m == n) {
return m;
}
while (m<n) {
n &= (n-1);
}
return n;
}