1. 程式人生 > >[劍指Offer] 15_二進位制中1的個數

[劍指Offer] 15_二進位制中1的個數

題目

面試題15:二進位制中1的個數
題目:實現一個函式,輸入一個整數,輸出該數二級製表示中1的個數。

例:
把9表示成二進位制是1001,有2位是1。因此如果輸入9,則該函式輸出2。


思路

  1. 最直接的思路:從低位開始向高位逐一比較是否為1, 並計數。
    1. 時間複雜度:O(n),num的二進位制位數
    2. 空間複雜度:O(1)
  2. 利用二進位制數的一個特點。A = /******…/ 1 /000000…/ 對於一個二進位制數其最後一個1的情況如左,對其 - 1 可得,A-1 = /******…/ 0 /111111…/ 。也就是說對一個二進位制數-1的後果是,最低位的1變為0,在其之後的所有0變為1。此時為了完成該位 1 消去為 0 的操作,A & A-1, /******…/部分將保留不變,後面的部分將全為0。因此只要不停做如上操作,直到A=0,計數即可。
    1. 時間複雜度:O(k),k=1的個數
    2. 空間複雜度:O(1)

程式碼

思路1:時間複雜度:O(n),空間複雜度:O(1)

def num_of_1_in_b(num):
    """
    due to number in Python3 has no bit limit
    so flag << 1 will never equals 0
    :param num:num
    :return:num of 1 in bin(num)
    """
    flag = 1
    count = 0
    for i in range(num.bit_length(
)): if flag & num: count += 1 flag <<= 1 return count

思路2:時間複雜度:O(k),空間複雜度:O(1)

def num_of_1_in_b_2(num):
    count = 0
    # will not work if num.bit_length() > 32
    # if num < 0:
    #     num = num & 0xffffffff
    while num:
        num = (
num - 1) & num count += 1 return count

思考

其實本題對於python來說有一點問題。
書上特意提示了對於負數的處理。在python中負數儲存比較不同。

>>> bin(3)
'0b11'
>>> bin(-3)
'-0b11'

同時python對數字沒有位數限制。因此就看個大概明白什麼意思就行了,想完全復現題目還得自己寫一個補碼儲存的func。

leetcode231. 2的冪

題目

給定一個整數,編寫一個函式來判斷它是否是 2 的冪次方。

示例 1:

輸入: 1
輸出: true
解釋: 20 = 1

示例 2:

輸入: 16
輸出: true
解釋: 24 = 16

示例 3:

輸入: 218
輸出: false

常規思路

class Solution(object):
    def isPowerOfTwo(self, n):
        """
        :type n: int
        :rtype: bool
        """
        if n == 0:
            return False
        while not(n % 2):
            n = n//2
        return True if n == 1 else False

位運算解法

class Solution(object):
    def isPowerOfTwo(self, n):
        """
        :type n: int
        :rtype: bool
        """
        return n > 0 and not (n & n-1)

位運算解法主要利用了一點,一個數如果是2的冪,二進位制一定為100…000,1後面n個0。
在結合本題所說的 A-1 & A可以消去最低位的1,那麼如果一個數A是2的冪 必有 A-1 & A == 0。