今天看到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, 因此此處不做區分
}
};
如代碼或分析有誤請批評指正,歡迎討論。