刷力扣随机算法题

第一天:比特位记数

给你一个整数 n ,对于 0 <= i <= n 中的每个 i ,计算其二进制表示中 1 的个数 ,返回一个长度为 n + 1 的数组 ans 作为答案。

示例 1:

输入:n = 2
输出:[0,1,1]
解释:
0 --> 0
1 --> 1
2 --> 10

   这个题就是找二进制中的1,刚开始看到计算二进制的值第一反应还没有思绪,用草稿纸将数字写到11就发现了规律,这个二进制中的1和当前计算的数是奇数,还是偶数有关,当数字

         当数字为奇数时,设数字为A,A中的二进制中的1的个数结果就是A除以2向下取整(这里设为B)的二进制数1的个数加1。

         当数字为偶数时,设当前数字为A,A中的二进制中的1的个数结果就是A除以2(这里设为B)的二进制数1的个数。

例如:

当A为17时:  17除以2向下取整为8(设为B),B的二进制位数中1有1个,A是奇数,所以得到1+1=2,这就是17的二进制中1的个数。

当A为22时:  22除以2向下取整为11(设B),B的二进制位数中1有3个,A是偶数,所以得到3,这就是22的二进制中1的个数。

很明显,这个里面存在着子问题,使用动态规划解决能够提升很多的时间。

上代码:

class Solution:
    def countBits(self, n: int) -> List[int]:
        res=[0 for i in range(n+1)]   
        for i in range(1,n+1):
            if i%2==0:  # 当i为偶数时
                res[i]=res[i//2]
            else:   # 当i为奇数时
                res[i]=res[i//2]+1
        return res

另外在计算数字中的二进制数时,看到一位博主方法的另外一种方法不错,

使用的是逻辑与运算得到,在不计算子问题的时候也提升了很多的速度。

0011 0100 - 1 = 0011 0011   
0011 0100 & 0011 0011 = 0011 0000  // 计数一个1
0011 0000 - 1 = 0010 1111
0011 0000 & 0010 1111 = 0010 0000  // 计数两个1
0010 0000 - 1 = 0001 1111
0010 0000 & 0001 1111 = 0000 0000  // 计数三个1,程序停止

具体详情查看

精妙的算法——计算二进制中1的个数 - 知乎 (zhihu.com)

你可能感兴趣的:(算法,python,算法,力扣)