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;
}
结果:

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

被折叠的 条评论
为什么被折叠?



