题目:比特位计数
- 给定一个非负整数
num
。对于0 ≤ i ≤ num
范围中的每个数字i
,计算其二进制数中的1
的数目并将它们作为数组返回。
示例 1:
输入: 2
输出: [0,1,1]
示例 2:
输入: 5
输出: [0,1,1,2,1,2]
进阶:
- 给出时间复杂度为O(n*sizeof(integer))的解答非常容易。但你可以在线性时间O(n)内用一趟扫描做到吗?
- 要求算法的空间复杂度为O(n)。
- 你能进一步完善解法吗?要求在C++或任何其他语言中不使用任何内置函数(如C++中的
__builtin_popcount
)来执行此操作。
来源:力扣(LeetCode)第338题
链接:https://leetcode-cn.com/problems/counting-bits
分析:
- 由于偶数的二进制数最后一位是0,所以如果一个偶数做
>>1
运算那么它的1的个数不变。同理如果一个奇数右移一位,1的个数减1。
- 因此如果1有1个1,那么2也有1个1,3就有2个1。(正推的话做左移运算),如果2有1个1的话,那么4也是1个1,5就是2个1。
- 所以有了状态转换公式
dp[2*i] = dp[i] dp[2*i+1] = dp[i] + 1
代码:
class Solution {
public int[] countBits(int num) {
int[] dp = new int[num + 1];
for (int i = 0; i <= num / 2; i++) {
dp[i<<1] = dp[i];
if ((i<<1) + 1 <= num) dp[(i<<1)+1] = dp[i] + 1;
}
return dp;
}
}
复杂度分析:
- 时间复杂度:O(n) n 为num / 2
- 空间复杂度:O(n) n 为num