1. 解析
题意,在[m, n]的范围内求位与,题目不难,关键是找出规律
2. 解析
我采用了一种本方法,没有利用规律.在一定范围内求所有数的位与,与运算我们都知道,当且仅当都为1时,结果为1,观察就可以发现,在[m, n]内求所有数的与取决于最小值m的位数,例如m=5,二进制为101,那么当最大值超过1000(8)之后,后面的计算就没有意义了,所以就可以将最小值m所表示位数的最大值替代掉n,这样可以大大减少不必要的计算
例如 [2, 100] 2-----10
在2个数位表示的范围最大值为11(3),那么我们只需计算[2, 4]范围内的与就行,超过2个数位的数(即大于4)都为0,没有必要计算
class Solution {
public:
int rangeBitwiseAnd(int m, int n) {
int cur = m;
long long int maxN = 1;
while (cur > 0){ //重新查找最大值
cur /= 2;
maxN *= 2;
}
maxN = maxN > n ? n : maxN;
int res = maxN;
while (m < maxN){ //依次求与
res &= m;
m++;
}
return res;
}
};
3. 利用规律
在[m, n]范围内的数,末尾几位都是一样的,i记录不一样的位数,最后右移回去就可以。例如 :
[5, 7] 5------101 6-----110 7------111
[10, 13] 10------1010 11------1011 12------1100 13------1101
class Solution {
public:
int rangeBitwiseAnd(int m, int n) {
int i = 0;
while (m != n){
m >>= 1;
n >>= 1;
i++;
}
return (m<<i);
}
};