先放Leetcode的四种方法,后边是我自己的理解与证明。
1.Brian Kernighan 算法->n&(n-1)可以消去二进制数n的末位1
2. 动态规划
(1)最高有效位
(2)最低有效位
(3)最低设置位
下面为可运行代码:
#include <iostream>
#include <vector>
using namespace std;
//比特位计数
// Kernighan算法
class Solution1
{
public:
int countones(int n)
{
int num = 0;
while (n > 0)
{
n &= (n - 1);
num++;
}
return num;
}
vector<int> countbits(int n)
{
vector<int> bits(n + 1);
for (int i = 0; i <= n; i++)
{
bits[i] = countones(i);
cout << bits[i] << " ";
}
return bits;
}
};
//动态规划-最高有效位
class Solution2
{
public:
vector<int> countBits(int n)
{
vector<int> bits(n + 1);
int high = 0;
bits[0] = 0;
cout << bits[0] << " ";
for (int i = 1; i <= n; i++)
{
if ((i & (i - 1)) == 0)
{
high = i;
}
bits[i] = bits[i - high] + 1;
cout << bits[i] << " ";
}
return bits;
}
};
//动态规划-最低有效位
class Solution3
{
public:
vector<int> countBits(int n)
{
vector<int> bits(n + 1);
cout << bits[0] << " ";
for (int i = 1; i <= n; i++)
{
bits[i] = bits[i >> 1] + (i & 1);
cout << bits[i] << " ";
}
return bits;
}
};
//动态规划-最低设置位
class Solution4
{
public:
vector<int> countBits(int n)
{
vector<int> bits(n + 1);
cout << bits[0] << " ";
for (int i = 1; i <= n; i++)
{
bits[i] = bits[i & (i - 1)] + 1 ;
cout << bits[i] << " ";
}
return bits;
}
};
int main()
{
Solution1 S1;
S1.countbits(10);
cout << endl;
Solution2 s2;
s2.countBits(10);
cout << endl;
Solution3 s3;
s3.countBits(10);
cout << endl;
Solution4 s4;
s4.countBits(10);
return 0;
}