- 338.比特位计数
- 题目:
输入一个num,输出一个长度为n+1的数组,元素分别为[ 0,num ]对应的二进制数的1的个数; - 思路:
1.暴力:时间O(32n),空间O(1)
遍历[ 0,num ],分别计算每个数的二进制的1的个数;
class Solution {
public:
vector<int> countBits(int num) {
vector<int> res(num + 1);
for (int i = 0; i <= num; ++i) {
int count = 0;
int j = i;
while (j) {
++count;
j &= (j - 1);//只找二进制为1的地方,不用逐位判断
}
res[i] = count;
}
return res;
}
};
2.最低有效位dp:O(n),O(1)
class Solution {
public:
vector<int> countBits(int num) {
vector<int> res(num + 1);
for (int i = 0; i <= num; ++i) {
//i>>1还是0,即i取0时,下面dp递推式结果正确,因此可以从0开始
res[i] = res[i >> 1] + (i & 1);//偶数右移不变,奇数右移少一个;(i>>1) < i
}
return res;
}
};
3.最低设置位dp:O(n),O(1)
class Solution {
public:
vector<int> countBits(int num) {
vector<int> dp(num + 1);
for (int i = 1; i <= num; ++i) {
//注意,下面用到了i-1,因此i不能从0开始
dp[i] = dp[i & (i - 1)] + 1;//i&(i-1) < i
}
return dp;
}
};
4.最高有效位dp:O(n),O(1)
class Solution {
public:
vector<int> countBits(int num) {
vector<int> dp(num + 1);
int highBit = 1;//初始化为1,是因为下面循环从1开始,此时的最高有效位的权重是1
for (int i = 1; i <= num; ++i) {
if ((i & (i - 1)) == 0) highBit = i;//每当i成为2的整数幂,此时二进制1的个数只有1个,在i成为下一个2的整数幂之前,最高有效位的权重始终是highBit
dp[i] = dp[i - highBit] + 1;//例如(5)10=(101)2, 去掉最高有效位的权重,即100对应的4之后,剩下的部分在之前都算过了(i-highBit < i)
}
return dp;
}
};