《leetCode》:Counting Bits

题目

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.

思路一:run time O(n*sizeof(integer))

就如提示所说,如果时间复杂度为O(n*sizeof(integer)),则就相当简单了。就是依次判断每个数的二进制表示中1的个数为多少。


int countBitOne(int a){
    if(a<0){
        return 0;
    }
    int count=0;
    while(a){
        int temp=a%2;
        count+=temp;
        a=a>>1;
    }
    return count;
}

int* countBits(int num, int* returnSize) {
    if(num<0){
        return NULL;
    }
    int *res=(int *)malloc((num+1)*sizeof(int));//注意:要开辟num+1个空间 
    for(int i=0;i<=num;i++){
        res[i]=countBitOne(i);
    }
    *returnSize=num+1;
    return res;
}

原以为按照这种思路来做,不会AC,没想到居然AC了。

思路二:时间复杂度为O(n)

思路:
当num<2时结果为:0 1
当num<4时结果为:0 1 1 2
当num<8时结果为: 0 1 1 2 , 1 2 2 3

从上面的结果可以看出,2^i~(2^(i+1))-1区间中数含1的个数为对应的 0~(2^i)-1
的1的个数加1.即

res[pow(2,i)+j]=res[j]+1;0<=j<pow(2,i)且pow(2,i)+j<=num;

实现代码如下:

int mypow(int a,int b){
    int res=1;
    for(int i=0;i<b;i++){
        res*=a;
    }
    return res;
}

int* countBits(int num, int* returnSize) {
    if(num<0){
        return NULL;
    }
    int *res=(int *)malloc((num+1)*sizeof(int));//注意:要开辟num+1个空间 
    if(res==NULL){
        printf("malloc failure");

    }
    res[0]=0;
    *returnSize=num+1;
    if(num==0){
        return res;
    }
    res[1]=1;
    if(num==1){     
        return res;
    }
    //先找到离num最近且大于num的2的幂次 
    int n=num;
    int count=1;
    while(n!=1){
        n=n>>1;
        count++;
    }   
    for(int i=1;i<count;i++){
        int powValue=mypow(2,i);
        for(int j=0;powValue+j<=num&&j<powValue;j++){//注意: powValue+j<=num
            res[powValue+j]=res[j]+1;
        }       
    }   
    return res;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值