题目
给定范围 [m, n],其中 0 <= m <= n <= 2147483647,返回此范围内所有数字的按位与(包含 m, n 两端点)。
示例 1:
输入: [5,7]
输出: 4
示例 2:
输入: [0,1]
输出: 0
思路
好久没有做题了,看到今天的每日一题是中等难度就冒个泡水一发。
看到位运算先找找规律:
- 2 2 & 2 3 = 0 \ 2^2 \& 2^3=0 22&23=0
- 8 & 9 = 8 \ 8 \& 9=8 8&9=8
- 8 & 9 & 10 = 8 \ 8 \& 9 \& 10=8 8&9&10=8
- 12 & 13 & 14 = 12 \ 12 \& 13 \& 14 = 12 12&13&14=12
由上面的式子可以得知:
- 若将小于m的最大的2的幂次称作m的级别(便于说明),当m和n的级别不相同时,结果为0.
- 当m和n的级别相同时,结果为m和n的二进制表示的公共前缀。
代码
class Solution {
public int rangeBitwiseAnd(int m, int n) {
if(m == 0 && n == 0)
return 0;
int m2 = cal(m), n2 = cal(n);
if(m2 != n2)
return 0;
else {
int result = 0;
while(m > 0) {
int mm = m & (1 << m2);
int nn = n & (1 << m2);
if(mm != nn)
break;
result += mm;
m -= mm;
n -= mm;
m2 --;
}
return result;
}
}
/**
* 计算不超过m的2的co次幂
* @param m
* @return
*/
private int cal(int m) {
int co = 0;
while (m > 0) {
m >>= 1;
co ++;
}
return co - 1;
}
}