算法课第十三周作业 | Counting Bits

来源:互联网 发布:逻辑回归 知乎 编辑:程序博客网 时间:2024/05/16 07:39

写在前面:

选取题目338,采用动态规划的方法解题。


题意解读:

给定一个非负整数num,输出每个大于等于0并小于等于num的整数二进制中的1的个数。

例如num=5,则输出[0,1,1,2,1,2]

计算时间复杂度要求和存储空间复杂度要求为O(n)


解题思路:

根据复杂度要求,所有处理只能在一个循环里面完成。

如果数出每个数的1的个数,有num个数,复杂度就会变成n*n

那么须得边计算边记录已得的结果并且利用前面的计算结果生成后面的结果。

观察0,1,2,3……的二进制表达:

0- 0
1- 1
2- 10
3- 11
4- 100
5- 101
6- 110
7- 111

我们可以发现,每次递增变化的都是最后一位,前面的部分有多少个1,可以用n>>1的个数,而最后1位是1就+1,反之则不用。

我们从0开始保存,前面的数字中1的位数已经保存,也即可以用通用公式:countOne(n) = countOne(n>>1) + n&1 


代码:

class Solution {public:    vector<int> countBits(int num) {        vector<int> countOne;          countOne.push_back(0);          for(int i = 1; i <= num; i++){              int count = countOne[i>>1] + (i&1);              countOne.push_back(count);          }          return countOne;    }};

运行结果:


原创粉丝点击