(leetcode338)比特位计数(模拟法、动态规划)

本文探讨了两种高效算法来计算二进制数中1的个数,一是通过模拟数字加1的过程,二是采用动态规划方法。动态规划方法基于奇偶数特性,对于奇数,只需在前一个偶数的基础上加1;对于偶数,其1的个数等于n/2的1的个数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原题如下:
在这里插入图片描述笔者思路比较正常,是模拟正常加1情况下的数字变化,规律如下:
1、当上一个字符中有0时,下一次运算会将最右位置的0置1,将这个0的位置x后的1全部改为0;
这个字符中1的个数为为n+1-(len(s)-1-x),其中n表示上个字符中1的个数,+1表示将最右边的0置1,(len(s)-1)-x代表原来0后边的1的个数,置为0以后减去即可。
2、当上一个字符没有0时,所有1变0,同时开头补1。
此时n的个数为1。

class Solution:
    def countBits(self, num: int) -> List[int]:

        s="0"
        n=0
        lst=[0]
        for index in range(1,num+1):
            if s.find("0")+1:
                x=s.rfind("0")
                s=s[:x]+"1"+"0"*(len(s)-1-x)
                n+=x+2-len(s)
            else:
                s="1"+"0"*len(s)
                n=1
            #print(s,n)
            lst.append(n)
        return lst

大佬思路(动态规划),原文链接
0中1的个数为0,对于此后的数字,:
(1)若为奇数,则相比于上一个偶数只是最后一位从0到1,n+=1即可,此时dp[n]=dp[n-1]+1。
(2)若为偶数,则其二进制相比于n/2只是左移一位,右边补0,即其中1的个数相等,dp[n]=dp[n//2]
笔者代码如下(其中判断奇偶采用了位运算x&1,奇数得1,偶数得0,比对2取余要快):

class Solution:
    def countBits(self, num: int) -> List[int]:
        dp=[0]
        for index in range(1,num+1):
            if index&1:
                dp.append(dp[-1]+1)
            else:
                dp.append(dp[index//2])
        return dp
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值