Leetcode刷题:剑指offer【面试题15 二进制中1的个数】

【面试题15 二进制中1的个数】

难度: 简单
考察: 位运算

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

Leetcode题目对应位置: 面试题15:二进制中1的个数

思路 1:自身移位

判断所给二进制数最右边第一位是否为 1,若是 1 则计数器加 1;接着将二进制数整体右移一位,此时再判断右边第一位是否为 1,一直循环到二进制数变为 0 为止。

问题转化为: 移位操作 & 判断二进制数最右边是否为 1

判断一个二进制数最右边是否为 1,可以用 1 与其做“与运算”。由于 1 除了最右边位为 1,其余位都为 0,所以与任意二进制数相与,若结果为 1,说明二进制数最右边位是 1,否则就是 0。

时间复杂度: O ( l o g 2 n ) O(log_2n) O(log2n) l o g 2 n log_2n log2n 表示所给数 n 最高位 1 的所在位数
空间复杂度: O ( 1 ) O(1) O(1)

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

思路 2:辅助移位

首先将 n 与辅助数字 1 做“与运算”,判断最右边位是否为 1;然后将辅助数字 1 左移一位,得到 10(十进制的 2),再和 n 做“与运算”判断。像这样不断将辅助数字左移,就能判断 n 的对应位置是否为 1。循环终止条件是移动后的辅助操作数大于 n。

时间复杂度: O ( l o g 2 n ) O(log_2n) O(log2n) l o g 2 n log_2n log2n 表示所给数 n 最高位 1 的所在位数
空间复杂度: O ( 1 ) O(1) O(1)

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

思路 3:使用n&(n−1)

将一个二进制数减去 1 的结果与原二进制数做“与运算”,会把该整数最右边的 1 变成 0,而其余位都不变。那么一个二进制数中有多少个 1,就进行多少次这样的操作,便能够统计出有多少个 1 了。这样做的好处是,二进制数中有几个 1 就循环几次,效率最高。

时间复杂度: O(m),m 为所给数字中 1 的个数,最坏情况下,m = n(数字位数)
空间复杂度: O(1)

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

需要注意的点:

  • 本题是无符号数,所以第一种方法可以运行通过,但如果是有符号数,且 n 为一个负数,不断将 n 右移会死循环,因为最高位会不断补 1
  • 二进制数 右移一位除以2 在数学上是等价的,但是除法效率比移位运算低很多,在实际编程中应该尽可能用移位运算代替除法运算
  • 整数减去 1 后与原整数做按位与运算,效果相当于将整数二进制表示中最右边的 1 变成 0,很多二进制问题都可以用该思路解决

参考资料:
[1] 剑指 offer 第二版
[2] LeetCode 刷题 面试题15:二进制中1的个数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不吃饭就会放大招

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值