題目描述
給定範圍 [m, n],其中 0 <= m <= n <= 2147483647,返回此範圍內所有數字的按位與(包含 m, n 兩端點)。
示例1
輸入: [5,7] 輸出: 4
示例2
輸入: [0,1] 輸出: 0
思路1
當一個數+1時,總會有這麼一個規律“某一位後的數字,全部被置爲相反數”。舉個例子:
- 010111 + 1 = 011000,則010111 & 011000 = 010000。那麼,x & (x+1) 後幾位相反數的“與操作”,結果總爲0。
所以,當(m,m+1,...n-1,n)進行連續“與操作”時,會按照上述規律被抵消很大一部分,而只剩下n的前綴部分,最後只需將n歸位。舉個例子:
- m = 5(0101), n = 7 (0111)。不停右移,得到n前綴部分爲01,最後歸位前綴得res=0100=4
實現
int rangeBitwiseAnd(int m, int n) {
int offset = 0;
for (; m != n; ++offset) {
m >>= 1;
n >>= 1;
}
return n << offset;
}
思路2
從高位向低位與,利用 n&(n-1)的特性: n & (n - 1) 可以將 n 最右邊的 1 變成 0
實現
int rangeBitwiseAnd(int m, int n) {
while (n > m) {
n &= (n - 1);
}
return n;
}
這思路和實現,給大神跪了!!!