Leetcode338. 比特位计数

这篇博客介绍了两种方法来解决计算整数二进制表示中1的个数的问题。解法一是通过观察奇偶数位的规律,利用动态规划实现;解法二是应用BrianKernighan算法,通过与运算递减找到1的个数。这两种方法都提供了高效的解决方案,并附有详细的代码实现。

Every day a leetcode

题目来源:338. 比特位计数

解法1:规律(真正的动态规划

对于整数i(1<=i<=n),

  • 若i为奇数,则i的二进制表示中1的个数一定比前面那个偶数i-1多一1,因为多的就是最低位的1
  • 若i为偶数,则i的最低位一定是0,则其二进制表示中1的个数一定等于i>>1,即i/2

代码:

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* countBits(int n, int* returnSize){
    int *ans;
    ans=(int*)malloc((n+1)*sizeof(int));
    ans[0]=0;
    *returnSize=n+1;
    for(int i=1;i<=n;i++)
    {
        if(i%2) ans[i]=ans[i-1]+1;
        else ans[i]=ans[i>>1];
    }
    return ans;
}

结果:
在这里插入图片描述

解法2:Brian Kernighan 算法

相关链接:Brian Kernighan 算法

该算法可以被描述为这样一个结论:

记 f(x) 表示 x 和 x-1 进行与运算所得的结果(即 f(x)=x & (x−1)),那么f(x) 恰为 x 删去其二进制表示中最右侧的 1 的结果。

于是,我们反复对一个数使用Brian Kernighan 算法,直到它为0,使用的次数即为其二进制表示中 1 的个数。

代码:

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */

//Brian Kernighan 算法
int bk(int x)
{
    int count=0;
    while(x)
    {
        x=x&(x-1);
        count++;
    }
    return count;
}

int* countBits(int n, int* returnSize){
    int *ans;
    ans=(int*)malloc((n+1)*sizeof(int));
    *returnSize=n+1;
    for(int i=0;i<=n;i++)
    {
        ans[i]=bk(i);
    }
    return ans;
}

结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

UestcXiye

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值