338. 比特位计数
- 比特位计数
难度中等349
给定一个非负整数 num。对于 0 ≤ i ≤ num 范围中的每个数字 i ,计算其二进制数中的 1 的数目并将它们作为数组返回。
示例 1:
输入: 2 输出: [0,1,1]
示例 2:
输入: 5 输出: [0,1,1,2,1,2]
1.位运算
// 问题分析 主要是计算出每个位数Num是否为1 并且当前的1的个数
//而本题的思路 显然不是按照这样做。而是把num分隔成多个数字来看当前的位数1的个数。
//比如 5 依次求出 1 2 3 4 5 添加到数组中,
// 时间复杂度 O(n*k) 空间复杂度O(n)
public int[] countBits(int num) {
int [] ans = new int [num+1];
for(int i=0;i<=num;i++){
ans[i] = popCount(i);
}
return ans;
}
//x = 0 count = 0
//x = 1 count = 1
//x = 2 count = 1
public int popCount(int x){
int count = 0;
for(;x!=0;count++){
x&= x-1;
}
return count;
}
2.dp
// dp[0] = 0
// dp[1] = 1
// dp[2] = 1
// dp[3] = 2
// dp[4] = 1
// dp[5] = 2
// 思路:dp
// 动态规划 我们需要考虑基础条件 0 = 0 1 = 1 而一个数字是奇数和偶数
// i%2 == 0 偶数 右移 i/2 等价于 右移1位 dp[i] = dp[i/2]的值
// i%1 == 1 奇数 上一个数字加上1 dp[i] = dp[i-1] + 1
// 时间复杂度为O(n) 空间复杂度为O(n)
public int[] countBits(int num) {
if(num==0) return new int[]{0};
int[] dp = new int[num+1];
dp[0] = 0;
dp[1] = 1;
for(int i=2; i<=num; i++){
if(i%2==0) dp[i]=dp[i/2];
else dp[i]=dp[i-1]+1;
}
return dp;
}