问题:
Given a range [m, n] where 0 <= m <= n <= 2147483647, return the bitwise AND of all numbers in this range, inclusive.
For example, given the range [5, 7], you should return 4.
解决:
【题意】将给定的范围m,n,之间的数按位与的结果。假设有m,m1,n1,n四个数,a=m&m1,b=a&n1,c = b & n的结果与m&m1&n1&n的结果相同。
① 暴力解决,超时。
class Solution {
public int rangeBitwiseAnd(int m, int n) {
if(m == 0) return 0;
int res = 2147483647;
for (int i = m;i <= n ;i ++ ) {
res = res & i;
}
return res;
}
}
② 从上面可以看出是位操作,要找规律了。
[5,7]:101 110 111 ----> 100
[26,30]:11010 11011 11100 11101 11110 ----> 11000
从上面的例子可以看出,最后数字为1的部分应该是左边的公共部分。所以只需要找到左边的公共部分即可。
建立一个32位都是1的mask,然后每次向左移一位,比较m和n是否相同,不同再继续左移一位,直至相同,然后把m和mask相与就是最终结果。
class Solution { //8ms
public int rangeBitwiseAnd(int m, int n) {
int mask = Integer.MAX_VALUE;
while((m & mask) != (n & mask)){
mask <<= 1;
}
return m & mask;
}
}
③ 直接平移m和n,每次向右移一位,直到m和n相等,记录下所有平移的次数i,然后再把m左移i位即为最终结果。
class Solution { //8ms
public int rangeBitwiseAnd(int m, int n) {
int count = 0;
while(m != n){
m >>= 1;
n >>= 1;
count ++;
}
return (m << count);
}
}
④ 如果m小于n就进行循环,n&n-1,去掉最低位的1即可。8ms
class Solution {
public int rangeBitwiseAnd(int m, int n) {
while(m < n){
n &= (n - 1);
}
return n;
}
}