[剑指Offer] 15_二进制中1的个数

版权声明:Tian Run https://blog.csdn.net/u013908099/article/details/85774640

题目

面试题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。

猜你喜欢

转载自blog.csdn.net/u013908099/article/details/85774640