【LeetCode】338. 計算比特位的數目

問題描述

Given a non negative integer number num. For every numbers i in the range 0 ≤ i ≤ num calculate the number of 1's in their binary representation and return them as an array.

Follow up:

  • It is very easy to come up with a solution with run time O(n*sizeof(integer)). But can you do it in linear time O(n) /possibly in a single pass?
  • Space complexity should be O(n).
  • Can you do it like a boss? Do it without using any builtin function like __builtin_popcount in c++ or in any other language.

給定一個非負整數num,對於0≤i≤num範圍內的每個數字i,計算其二進制表示中的1的個數,並將它們作爲數組返回。
跟進:

  • 用運行時O(n*sizeof(integer))提出一個解決方案是非常容易的。但你能在線性時間O(n)內完成嗎?
  • 空間複雜度應該是O(n)。
  • 你能像老闆那樣做嗎?在c++或其他任何語言中都不需要使用任何內建函數,如_builtin_popcount。
輸入: 2
輸出: [0,1,1]

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

 

Python 實現

實現一:轉化成二進制數後數 ‘1’ 的個數。不用說,這是一個很耗內存的實現方法,每次轉換成二進制數時都需要使用新的內存。

class Solution(object):
    def countBits(self, num):
        """
        :type num: int
        :rtype: List[int]
        """
        
        bitCnt = [0]
        for n in range(1,num+1):
            bitCnt.append(format(n,'b').count('1'))
            
        return bitCnt

實現二:尋找規律。二進制數與 2 的 n 次方有很密切的關係,那麼我們可以觀察一下當入參 num 爲 2 的 n 次方時,所得的結果有什麼規律:

[0]
[0, 1]
[0, 1, 1, 2]
[0, 1, 1, 2, 1, 2, 2, 3]
[0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4]
...

沒看出來?給個提示:看看每一個數組中,新增的後半部分元素與前半部分有什麼關係。

沒錯,後半部分的每一個元素相當於前半部分每個元素加一後的結果。

但是這個方法存在一個缺點就是,當入參 num 較大時,一個極端情況 num = 2^n + 1,這樣我們就需要計算到 2^(n+1),但後面的 2^n - 1 個數都會被拋棄,因此存在着運算資源的浪費。

class Solution(object):
    def countBits(self, num):
        """
        :type num: int
        :rtype: List[int]
        """
        
        bitCnt = [0]
        while len(bitCnt) < num+1:
            bitCnt.extend([i+1 for i in bitCnt])
            
        return bitCnt[:num+1]

實現三:動態規劃。

分析相鄰兩個整數在二進制表示下的關係。如果 n 是奇數,那麼其最低比特位爲1,則 n>>1 (表示 n 右移一位)出現 1 的個數再加 1 就是 n 出現 1 的個數(奇數右移一位會丟失最低位的 1);如果 n 是偶數,則右移一位後,出現 1 的個數不變。其中,我們所要知道的 n>>1 出現 1 的個數,必然在前面計算已經得到,所以這一題可以使用動態規劃來解決。

class Solution(object):
    def countBits(self, num):
        """
        :type num: int
        :rtype: List[int]
        """

        bitCnt = [0]*(num+1)
        for i in range(1, num+1):
            bitCnt[i] = bitCnt[i>>1] + i%2
        return bitCnt

 

鏈接:https://leetcode.com/problems/counting-bits/

發佈了46 篇原創文章 · 獲贊 29 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章