LeetCode-338. Counting Bits

梦里梦外; 2022-07-26 00:07 235阅读 0赞

Problem:

  1. Given a non negative integer number num. For every numbers i in the range 0 i num calculate the number of 1's in their binary representation and return them as an array.
  2. Example:
  3. For num = 5 you should return [0,1,1,2,1,2].
  4. Follow up:
  5. It is very easy to come up with a solution with run time O(n*sizeof(integer)). But can you do it in linear time O(n) /possibly in a single pass?
  6. Space complexity should be O(n).
  7. Can you do it like a boss? Do it without using any builtin function like __builtin_popcount in c++ or in any other language.

Analysis:
题目大意

给定一个非负整数num。对于每一个满足0 ≤ i ≤ num的数字i,计算其数字的二进制表示中1的个数,并以数组形式返回。
测试用例如题目描述。
进一步思考: 很容易想到运行时间 O(n*sizeof(integer)) 的解法。但你可以用线性时间O(n)的一趟算法完成吗? 空间复杂度应当为O(n)。
你可以像老板那样吗?不要使用任何内建函数(比如C++的__builtin_popcount)。

提示

  • 你应当利用已经生成的结果。
  • 将数字拆分为诸如 [2-3], [4-7], [8-15]之类的范围。并且尝试根据已经生成的范围产生新的范围。
  • 数字的奇偶性可以帮助你计算1的个数吗?

方法1 利用了位运算i&(i-1),这个运算可以去除最右边的1,思想是利用已经计算过的值再加1得到要计算的值。

  1. public class Solution {
  2. public int[] countBits(int num) {
  3. int[] res = new int[num+1];
  4. res[0]=0;
  5. for(int i=1;i<=num;i++){
  6. res[i]=res[i&(i-1)]+1;
  7. }
  8. return res;
  9. }
  10. }

方法2 是根据提示将数分为诸如 [2-3], [4-7], [8-15]之类的范围,在数满足2的n次方的时候记录这个范围中的最小数(这个范围的数都是在这个最小数的基础上增加)的1的个数和这个数的大小值。然后利用以前计算过的数进行DP。

  1. public class Solution {
  2. public int[] countBits(int num) {
  3. if (num==0) return new int[]{
  4. 0};
  5. int[] x=new int[num+1];
  6. x[0]=0;
  7. x[1]=1;
  8. int seed=1;
  9. for (int i=2;i<num+1;i++){
  10. if (i==seed*2 ){
  11. x[i]=1;
  12. seed=i;
  13. continue;
  14. }
  15. x[i]=x[i-seed]+1;
  16. }
  17. return x;
  18. }
  19. }

发表评论

表情:
评论列表 (有 0 条评论,235人围观)

还没有评论,来说两句吧...

相关阅读