分析
如果真的在范圍[m, n]內按順序逐個數字做&操作顯然效率不高。那么我們可以先列出一些數字去尋找規律:
12 1100 110 11
13 1101 110 11
14 1110 111 11
15 1111 111 11
上表區間中在移位過程中,逐漸抹去最后一位,最終會在某一次移位后區間內所有數的值相同(1101->110->11),移位次數為2,該范圍內所有數按位與操作以后結果為1100,即12。由此我們可以知道,低位部分在范圍內按位與操作中會因為0的存在而消去為0,只有高位部分會得以保留。因此我們可以用一個count計數器記錄移位次數(即低位0的個數),而最終移位結果均一致時(如例子中最終為二進制11),即為其高位部分。此時只需將高位部分復原即可,也就是11->110->1100,做2次向左移位復原。
當然在計算過程中我們并不需要對區間內所有數做這種操作,只需對區間最小值m和最大值n進行操作(因為區間首尾是區分度最大的兩個數,對區間內所有數做右移時,最有可能不相同的肯定是m和n)。
注意
當較小的數移位后為0時,就應該停止循環。最終結果肯定也是0。
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, 因此此處不做區分
}
};