1. 程式人生 > 實用技巧 >leetcode [201. 數字範圍按位與]

leetcode [201. 數字範圍按位與]

(https://leetcode-cn.com/problems/bitwise-and-of-numbers-range/)

關鍵是理解官方題解中的這句話:對所有數字執行按位與運算的結果是所有對應二進位制字串的公共字首再用零補上後面的剩餘位。

其實想一想很好理解,給你一個範圍[a,b],那麼a,b的左邊肯定有一些二進位制位上的數是相同的(公共字首),而從a變化到b在二進位制上,他的公共字首是不變的,變得是右邊的二進位制位上的數。那為什麼右邊的二進位制位全都要補0呢?假如我們給二進位制位標上號,從左到右依次為0、1、2....,現在我們已經知道了0-i是公共字首,說明所有數的第i+1位不是完全相同的,而我們知道二進位制越往左所代表的數越大,所以在a-b逐加1的過程中肯定有一個數,是i+1位上的轉折點,在他之前的一個數i+1位為0,後面所有的位為1,到它了加1一直進位就變成了i+1位為1,後面所有的位為0。而按位與只要有一個數位為0,那就一直為0,我們可以藉助這兩個數的特殊性,得到官方題解中的:“用零補上後面的剩餘位”這句話。

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

小結:用左右移符號竟然比直接用*/2快一倍!