一、 题目
给出一个范围,这个范围在0--2147483647,返回在这一个范围的所有整数的与操作值。这个范围包括两个边界。
例如:给出[5,7] 返回的是4
二、 分析
或许我们最能轻易想到的是使用暴力解法,即将范围中的数依次与操作,但是这样势必会超时。那么该如何做呢?我们做与操作其实是在将这些数二进制中相同位置不同值的去掉,留下相同的,在《编程之美》中有一个求一个数中1的个数的题目,在此我们可以借鉴这个方法,每次使n和n-1相与,直到n=m,返回m&n即可。这个是该方法的活用。
如果深入想一下的话,我们是要求得m--n中所有数的前缀(二进制),那么说到底是求m和n的前缀,所以我们可以每次将m和n后移一位,并计数,直到两者相等,再将该值左移cou位即可。
class Solution {
public:
int rangeBitwiseAnd(int m, int n) {
while(n>m)
n = n&n-1;
return m&n;
}
};
class Solution {
public:
int rangeBitwiseAnd(int m, int n) {
int cou = 0;
while(n != m){
n>>=1;
m>>=1;
cou++;
}
return m<<cou;
}
};