leetcode - [位运算] -(1)比特位计数

这篇博客介绍了如何解决LeetCode中的一个位运算问题,即计算给定负整数二进制表示中1的个数。提供了两种解题思路:一种是通过不断减1和与操作,另一种是使用动态规划。每种方法都详细解释了其工作原理,并且提到了各自的时间复杂度。
摘要由CSDN通过智能技术生成

1、问题描述

输入一个负整数num,对于 0 ≤ i ≤ n u m 0\le i \le num 0inum中的每个数 i i i,计算其二进制表示中1的个数,并将它们作为数组返回。

2、解题思路

  • 思路1:参考《剑指offer》-[第2章:面试需要的基础知识 - 2.4:算法与数据操作- 2.4.3:位运算] 题10:二进制中1出现的次数,对于每个整数,要想知道其二进制表示中1的个数,可以不断地对该数进行减1然后与自身与操作,知道该数变成0为止。减1实际上是将该数二进制表示中右边地第一个1变成0,然后与自身与完之后,右边第一个1及其后面所有的数都会变成0。由于这个整数有多少个1,就要进行多少次这样额操作,所以时间复杂度为 O ( n ∗ s i z e o f ( I n t e g e r ) ) O(n*sizeof(Integer)) O(nsizeof(Integer))
  • 思路2:也可以采用动态规划解决。对于0-num的所有数字,无非分为两类,奇数和偶数。
  • 由于奇数的二进制表示中的最后一位一定是1,偶数的二进制表示最后一位一定是0。所以,如果将它们分别除以2,那么
  • 对于每一个奇数来说,它的二进制表示中1的个数一定比它除以2的那个数的二进制表示中1的个数多1,因为除以2是右移1位,相当于把该数末尾的那个1去掉了;比如1=0001,3=0011;2=0010,5=0101。
  • 对于每一个偶数来说,它的二进制表示中1的个数一定和它除以2的那个数的二进制表示中1的个数相等,因为除以2是右移,相当于把该偶数末尾的0去掉了。例如:1=0001,2=0010;4=0100,8=1000.
  • 所以,动态规划的状态转移方程是:
  • B i t ( n ) = { B i t ( n / 2 ) + 1 i f   n 为 奇 数 B i t ( n / 2 ) i f   n 为 偶 数 Bit(n)=\begin{cases}Bit(n/2) + 1 & if \ n为奇数\\ Bit(n/2) & if \ n为偶数 \end{cases} Bit(n)={Bit(n/2)+1Bit(n/2)if nif n
    这种方法的时间复杂度为 O ( n ) O(n) O(n)

3、代码实现

class Solution:
    def countBits(self, num: int) -> List[int]:
        result = [0] * (num + 1)
        for i in range(0, num + 1):
            if i & 1 == 0:
                result[i] = result[i>>1]
            else:
                result[i] = result[i>>1] + 1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Albert_YuHan

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

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

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

打赏作者

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

抵扣说明:

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

余额充值