剑指 Offer 15. 二进制中1的个数

剑指 Offer 15. 二进制中1的个数

题目描述:

请实现一个函数,输入一个整数,输出该数二进制表示中 1 的个数。例如,把 9 表示成二进制是 1001,有 2 位是 1。因此,如果输入 9,则该函数输出 2。

示例:
输入:00000000000000000000000000001011
输出:3
解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 '1'。

输入:00000000000000000000000010000000
输出:1
解释:输入的二进制串 00000000000000000000000010000000 中,共有一位为 '1'。

# good trick
class Solution:
    def hammingWeight(self, n: int) -> int:
        return bin(x).count('1') # bin(n)返回的类型是字符型。采用str.count('1')进行计数即可。
        

1.Python中的整型是补码形式存储的

bin(-1)
'-0b1'

2.Python中bin一个负数(十进制表示),输出的是它的原码的二进制表示加上个负号,方便查看。

如果一个整数不为0,那么这个整数至少有一位是1。如果我们把这个整数减1,那么原来处在整数最右边的1就会变为0,原来在1后面的所有的0都会变成1(如果最右边的1后面还有0的话)。其余所有位将不会受到影响。
把原来的整数和减去1之后的结果做与运算,从原来整数最右边一个1那一位开始所有位都会变成0。

方法一:逐位判断
根据 与运算 定义,设二进制数字 n ,则有:
若 n & 1 = 0,则 n 二进制 最右一位 为 00 ;
若 n & 1 = 1 ,则 n 二进制 最右一位 为 11 。
根据以上特点,考虑以下 循环判断 :
判断 n 最右一位是否为 11 ,根据结果计数。
将 n 右移一位(本题要求把数字 n 看作无符号数,因此使用 无符号右移 操作)。
算法流程:
初始化数量统计变量 res = 0
循环逐位判断: 当 n = 0时跳出。
res += n & 1 : 若 n & 1 = 1,则统计数 res 加一。
n >>= 1 : 将二进制数字 n无符号右移一位( Java 中无符号右移为 “>>>>>>” ) 。
返回统计数量 res。

class Solution:
    def hammingWeight(self, n: int) -> int:
        res = 0
        while n:
            res += n & 1
            n >>= 1
        return res

方法二:巧用 n & (n - 1)
(n - 1) 解析: 二进制数字 n最右边的 1 变成 0 ,此 1 右边的 0 都变成 1 。
n&(n−1) 解析: 二进制数字 n最右边的 1 变成 0,其余不变。

Picture10.png

算法流程:
初始化数量统计变量 res 。
循环消去最右边的 1 :当 n = 0时跳出。
res += 1 : 统计变量加 1 ;
n &= n - 1 : 消去数字 n最右边的 1 。
返回统计数量 res。

class Solution:
    def hammingWeight(self, n: int) -> int:
        res = 0
        while n:
            res += 1
            n &= n - 1 #每执行一次就会将n最右边的一个1消去一个。统计循环的次数就是1的个数。
        return res
备注:

1.语法:str.count(“char”, start,end) 或 str.count(“char”) -> int 返回整数

str —— 为要统计的字符(可以是单字符,也可以是多字符)。
star —— 为索引字符串的起始位置,默认参数为0。
end —— 为索引字符串的结束位置,默认参数为字符串长度即len(str)。

为要统计的字符(可以是单字符,也可以是多字符)。
star —— 为索引字符串的起始位置,默认参数为0。
end —— 为索引字符串的结束位置,默认参数为字符串长度即len(str)。

2.对于二进制的编码的有符号数和无符号数需要了解一下。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值