动态规划例题(二)

一、leetcode地址

leetcode地址:https://leetcode-cn.com/problems/counting-bits/

二、题目 比特位计数

给定一个非负整数 num。对于 0 ≤ i ≤ num 范围中的每个数字 i ,计算其二进制数中的 1 的数目并将它们作为数组返回。例如:
输入: 2
输出: [0,1,1]

三、解法

先分析,然后找规律,最后求解。

1、统计法

直接利用求二进制的函数,进行统计“1”的数量统计即可

class Solution:
    def countBits(self, num: int) -> List[int]:
        res=[]
        for i in range(num+1):
            res.append(bin(i).count('1'))
        return res

2、递归

在做这一题的时候,二进制之间的规律并不清楚,我就在本子上从0开始写,然后规律就出现了

十进制数字 转为二进制 ‘1’的个数
0 0 0
1 1 1
2 10 1
3 11 2
4 100 1
5 101 2
6 110 2
7 111 3
8 1000 1
9 1001 2
... ... ...
我们可以得到的信息是:
1、偶数的二进制末尾为0,奇数的二进制末尾为1,所以第一n个数是奇数的情况下,第n个数字的二进制中的‘1’的个数一定比第(n-1)个数字二进制中的‘1’的个数多1个。
2、当第n个数字为偶数时,第n个数字的二进制数右移一位就是第n/2的二进制数(这个是二进制的位运算),因为偶数二进制末尾为‘0’,故‘1’的个数不变。
递归的代码如下:
class Solution:
    def countBits(self, num: int) -> List[int]:
        res=[]
        for i in range(num+1):
            res.append(self.count(i))
        return res

    def count(self,num):
        if num==0:
            return 0
        if num % 2==1:
            return self.count(num-1)+1
        return self.count(num//2)

3、动态规划

利用递归总结的规律,记录每一步的信息,直接调用值计算即可
代码如下:

class Solution:
    def countBits(self, num: int) -> List[int]:
        res=[0]*(num+1)
        for i in range(1,num+1):
            res[i]=res[i>>1]+(i&1)
        return res

小提示:‘i>>1’表示位运算右移一位,‘i&1’表示奇偶性,奇数值为1,偶数值为0

posted @ 2021-03-05 18:21  lvsling  阅读(86)  评论(0编辑  收藏  举报