题目:https://leetcode-cn.com/problems/bitwise-and-of-numbers-range/
给定范围 [m, n],其中 0 <= m <= n <= 2147483647,返回此范围内所有数字的按位与(包含 m, n 两端点)。
思路:一种直观解法是将(n,m)的不同地位部分都变为0,可以逐位右移,再左移回来即可,这个做法挺快的。
而还有一种可以利用我们的树状数组的lowbit来搞,如下。
class Solution {
public:
int rangeBitwiseAnd(int m, int n) {
while(n > m) n &= (n-1);
return n;
}
};
class Solution {
public int rangeBitwiseAnd(int m, int n) {
return n & ~(allOneAfterhighestBit(m^n));
}
int allOneAfterhighestBit(int i) {
i|=i>>1; // 1xxxxx...最高位复制了一个1到后面 =>11xxxxx... 有2个1
i|=i>>2; // 11xxxx...复制了2位1 => 1111xxxx... 有4个1
i|=i>>4; // 1111xxxx...复制了4个1 =>11111111xxx... 有8个1
i|=i>>8; // 11111111xxx... 复制了8个1 => 1111111111111111xxx... 有16个1
i|=i>>16; // 1111111111111111xxx... 复制了16个1 => 11111111...1111 有32个1
// 如果i最高位不足8或者16等,操作相当于|0,不变,所以此时的i变成了最高位后全是1x
return i;
}
}