1. 程式人生 > 其它 >數字範圍按位與

數字範圍按位與

技術標籤:Java演算法資料結構java演算法資料結構

給定範圍 [m, n],其中 0 <= m <= n <= 2147483647,返回此範圍內所有數字的按位與(包含 m, n 兩端點)。

示例 1:

輸入: [5,7]
輸出: 4

示例 2:

輸入: [0,1]
輸出: 0

解題思路:統計兩個數二進位制表示的公共字首

因為假設兩個數在第i位前面都相同,第i位一個為0,一個為1,那麼這兩個數之間一定存在一個數,這個數的第i位為1,且後面的都是0。這樣 ‘按位與’ 之後i位以及之後就都是零了。

所以求兩個數的公共字首即可。
通過兩個數不斷右移,直到兩個數相等。
再左移對應的位數

Java程式碼如下:

public int rangeBitwiseAnd(int m, int n) {
        int i = 0;
        while (m != n){
            m >>= 1;
            n >>= 1;
            i ++;
        }
        return m << i;
    }

補充:最直觀的解決方案就是迭代範圍內的每個數字,依次執行按位與運算,得到最終的結果,但此方法在 [m,n] 範圍較大的測試用例中會因超出時間限制而無法通過。
迭代範圍內的所有數會導致超時:

 public int rangeBitwiseAnd(int m, int n) {
        int result = m;
        while (m < n)
            result &= m++ + 1;
        return result;
    }

但注意到,當按位與的結果為0時,後面的數再執行,結果也都為0.所以當按位與的結果為0時就可以終止迴圈:

 public int rangeBitwiseAnd(int m, int n) {
        int result = m;
        while (m < n &&
result != 0) result &= m++ + 1; return result; }

如此用時604毫秒,並未超時。