LeetCode-338. Counting Bits

来源:互联网 发布:万网单域名管理平台 编辑:程序博客网 时间:2024/04/27 07:32

Problem:

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.Example:For num = 5 you should return [0,1,1,2,1,2].Follow up: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?Space complexity should be O(n).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得到要计算的值。

public class Solution {    public int[] countBits(int num) {        int[] res = new int[num+1];        res[0]=0;        for(int i=1;i<=num;i++){            res[i]=res[i&(i-1)]+1;        }        return res;    }}

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

public class Solution {    public int[] countBits(int num) {        if (num==0) return new int[]{0};        int[] x=new int[num+1];        x[0]=0;        x[1]=1;        int seed=1;        for (int i=2;i<num+1;i++){            if (i==seed*2 ){                x[i]=1;                seed=i;                continue;            }            x[i]=x[i-seed]+1;        }        return x;    }}
0 0
原创粉丝点击