今天看到Leetcode又有新题了。
原题:
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],0 <= m <= n <= 2147483647,求出该范围内所有数按位与(&)操作后的结果。比如范围[5, 7],为5&6&7 = 4。
分析:
如果真的在范围[m, n]内按顺序逐个数字做&操作显然效率不高。那么我们可以先列出一些数字去寻找规律:
0 | 0 |
1 | 1 |
2 | 10 |
3 | 11 |
4 | 100 |
5 | 101 |
6 | 110 |
7 | 111 |
8 | 1000 |
9 | 1001 |
10 | 1010 |
11 | 1011 |
12 | 1100 |
13 | 1101 |
14 | 1110 |
15 | 1111 |
... | ... |
再看其中的一个区间,举例[12, 15]:
12 | 1100 | 110 | 11 |
13 | 1101 | 110 | 11 |
14 | 1110 | 111 | 11 |
15 | 1111 | 111 | 11 |
当然在计算过程中我们并不需要对区间内所有数做这种操作,只需对区间最小值m和最大值n进行操作(因为区间首尾是区分度最大的两个数,对区间内所有数做右移时,最有可能不相同的肯定是m和n)。
注意:
当较小的数移位后为0时,就应该停止循环。最终结果肯定也是0。
如果还有困惑请看Ac代码。
AC代码(C++实现):
class Solution {
public:
int rangeBitwiseAnd(int m, int n) {
int count = 0;//初始化计数器
while (m && m != n) {//m为0时或m == n时退出循环
++count;//统计低位0的个数
m >>= 1; n >>= 1;//抹去低位
}
return m << count;//低位复原, 因为0 << count仍为0, 因此此处不做区分
}
};
如代码或分析有误请批评指正,欢迎讨论。