• 【Python3】【力扣题】338. 比特位计数


    【力扣题】题目描述:

    题解:从0到n的整数,逐一统计二进制中1的个数,记录在一个新列表中。

    【Python3】代码:

    1、解题思路:Python函数。

    知识点:bin(...):转为二进制字符串,即"0bxxx"。

                  字符串.count(...):统计字符串中某字符出现的次数。

                  列表.append(...):往列表尾部添加元素。

                  列表推导式:用简洁的方式创建列表。即 [ 对元素的简单操作 for 变量 in 可迭代对象 ]

    1. class Solution:
    2. def countBits(self, n: int) -> List[int]:
    3. res = [bin(i)[2:].count("1") for i in range(n+1)]
    4. return res
    5. #相当于
    6. res = []
    7. for i in range(n+1):
    8. res.append(bin(i)[2:].count("1"))
    9. return res

    2、解题思路:Brian Kernighan算法。

    每次将整数的二进制最低位的1消除为0,直到整数变为0。消除多少次则二进制中有多少个1。

    num &= (num-1) 即 num = num & (num-1) 。

    相当于将二进制最低位的1消除为0。若num为2的整数幂,则num&(num-1)=0。

    例如:num=5(二进制101),num-1=4(二进制100),num&(num-1)=101&100=100(即将101的最低位的1消除为0)。

    1. class Solution:
    2. def countBits(self, n: int) -> List[int]:
    3. res = []
    4. for i in range(n+1):
    5. cou = 0
    6. while i > 0:
    7. i &= (i-1)
    8. cou += 1
    9. res.append(cou)
    10. return res
    11. # 或者
    12. def count_one(num):
    13. cou = 0
    14. while num > 0:
    15. num &= (num-1)
    16. cou += 1
    17. return cou
    18. res = [count_one(i) for i in range(n+1)]
    19. return res

    3、解题思路:动态规划。

    将一个问题拆分成多个子问题,解决子问题并记录子问题的结果减少重复计算,最终整个问题解决。

    (3-1)若num是2的整数幂,num中只有最高位有1,则记录num。

    若num不是2的整数幂,则num的二进制 比 去除最高位之后的二进制 多一个1。

    例如:5(二进制101),去除最高位之后的二进制01(其个数已统计过为1),则5的二进制中1的个数为1+1=2个。

    1. class Solution:
    2. def countBits(self, n: int) -> List[int]:
    3. # 动态规划--最高有效位
    4. res = [0]
    5. high = 0 # 记录最高有效位即二进制中只有最高位有一个1
    6. for i in range(1,n+1):
    7. if i & (i-1) == 0:
    8. high = i
    9. res.append(res[i-high] + 1)
    10. return res

    (3-2)将二进制右移一位,去除最低位之后的二进制中1的个数已统计过;被去除的最低位若为1则结果中再加1。

    例如:5(二进制101),右移一位之后的二进制10(其个数已统计过为1),被去除的最低位为1则5的二进制中1的个数为1+1=2个。

    知识点:num >> 1:将num二进制右移一位。

                  i & 1:将num与1进行二进制与运算。

    1. class Solution:
    2. def countBits(self, n: int) -> List[int]:
    3. # 动态规划-最低有效位
    4. res = [0]
    5. for i in range(1,n+1):
    6. res.append(res[i >> 1] + (i & 1))
    7. return res

    (3-3)num&(num-1)消除num最低位的1,则num 比 消除最低位1之后 多一个1。

    例如:num=5(二进制101),num-1=4(二进制100),num&(num-1)=101&100=100,二进制100其个数已统计过为1,则5的二进制中1的个数为1+1=2个。

    1. class Solution:
    2. def countBits(self, n: int) -> List[int]:
    3. # 动态规划--最低设置位
    4. res = [0]
    5. for i in range(1,n+1):
    6. res.append(res[i & (i-1)] + 1)
    7. return res

  • 相关阅读:
    虚拟运营商与实体运营商的apn匹配逻辑
    计算机毕业设计django基于python的宠物分享网站(源码+系统+mysql数据库+Lw文档)
    Opencv cuda版本在ubuntu22.04中安装办法,解决Could NOT find CUDNN的办法
    如何修复-谷歌浏览器-打开任何一个网页都显示崩溃
    mysql command not found 找不到mysql命令
    Python断言(assert)
    合并分支导致的问题
    兼容IE全版本及所有市面浏览器的网页变黑白处理方式
    什么是列式存储和行式存储
    计算机网络——物理层
  • 原文地址:https://blog.csdn.net/yannan20190313/article/details/134533369