剑指 Offer 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的个数

  1. 若n & 1 = 0,则二进制最后一位为0
  2. 若 n & 1 = 1,则二进制最后一位为1

根据此特性,可以循环判断n的最后一位是1 还是 0,此时为了每次判断n的最后一位,需要将n进行右移操作:n >> 1

代码:(时间复杂度O(log2 n),n代表最高位1所在位数)

def hammingWeight(self, n: int) -> int:
        res = 0
        while n:
            res += n & 1 # n与1相与,,为0的话最后一位为0,为1的话最后一位为1
            n >>= 1 #右移
        return res
  • 解法二:用n&(n-1)

找 n & (n -1)特性:

(n−1) 解析: 二进制数字 nn 最右边的 11 变成 00 ,此 11 右边的 00 都变成 11 。

n \& (n - 1)n&(n−1) 解析: 二进制数字 nn 最右边的 11 变成 00 ,其余不变。

看图就懂了

 

  代码:时间复杂度O(M)(M为二进制中1的个数)

    def hammingWeight(self, n: int) -> int:
        res = 0
        while n:
            res += 1 # 此时肯定存在1个1
            n = n & (n-1) #将从右往左数第一个1消掉
        return res

 

逐位判断

posted @ 2020-08-02 16:33  Yelush  阅读(115)  评论(0编辑  收藏  举报