[LeetCode](面試題15)二進制中1的個數

題目

請實現一個函數,輸入一個整數,輸出該數二進制表示中 1 的個數。例如,把 9 表示成二進制是 1001,有 2 位是 1。因此,如果輸入 9,則該函數輸出 2。

示例 1:

輸入:00000000000000000000000000001011
輸出:3
解釋:輸入的二進制串 00000000000000000000000000001011 中,共有三位爲 '1'。

示例 2:

輸入:00000000000000000000000010000000
輸出:1
解釋:輸入的二進制串 00000000000000000000000010000000 中,共有一位爲 '1'。

示例 3:

輸入:11111111111111111111111111111101
輸出:31
解釋:輸入的二進制串 11111111111111111111111111111101 中,共有 31 位爲 '1'。

解題思路

解法一:逐位判斷

首先把1和n做位運算,判斷n的最低位是不是1。接着把1左移一位變成2,和n做位運算,判斷n的次低位是不是1。這樣反覆左移,逐位判斷n的每一位是不是1。

複雜度分析:
時間複雜度:O(M),M表示整數二進制的位數,因爲循環次數等於整數二進制的位數,例如32位整數需要循環32次。
空間複雜度:O(1)。

解法二:巧用 n&(n−1)

1)假設一個整數的最右邊一位爲1,減去1之後,最後一位變成0,其他所有位保持不變。
2)假設最後一位不是1而是0,如該整數的二進制表示中最右邊的1位於第m位,那麼減去1之後,第m位由1變成0,第m位之後的所有0變成1,第m位之前的所有數保持不變。
以上兩種情況,歸納起來就是把一個整數減去1,都是把最右邊的1變成0。如果它的右邊還有0,則把所有的0變成1,而它左邊的所有數保持不變。接下來,將這個整數減去1之後的結果,再和原來的整數做位運算,得到的結果相當於把整數的二進制表示中最右邊的1變成0,一個整數的二進制表示中有多少個1就進行幾次這樣的操作。

複雜度分析:
時間複雜度:O(M),設 M 爲二進制數字 n 中 1 的個數,則需循環 M 次(每輪消去一個 1 ),佔用 O(M)。
空間複雜度:O(1)。

代碼

解法一:逐位判斷

public class Solution {
    // you need to treat n as an unsigned value
    public int hammingWeight(int n) {
        int count = 0;
        int flag = 1;
        while(flag!=0){
            if((n & flag)!=0){
                count++;
            }
            flag <<= 1;
        }
        return count;
    }
}

解法二:巧用 n&(n−1)

public class Solution {
    // you need to treat n as an unsigned value
    public int hammingWeight(int n) {
        int count = 0;
        while(n!=0){
            n = n & (n-1);
            count++;
        }
        return count;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章