0. 题目描述
剑指 Offer II 003. 前 n 个数字二进制中 1 的个数
2. 解题思路分析
- 如何计算每个数对应的 1 的个数
- 位运算核心代码
for(int i = 0; i <= n; i++){
int t = i;
while(t > 0){
ans[i] += t & 1;
t = t >> 1;
}
}
注意:这里不能用 i 直接位移,因为每次i都会右移到0,相当于是循环每次都从0开始
3. 动态规划思想分析
-
关于动态规划问题的初步了解,1,3,5 =》11硬币
Java动态规划算法
dp[i] = min(dp[i - 1] + 1, dp[i - 3] + 1, dp[i - 5] + 1) -
尝试推导该题的动态规划算法
关键:找到 dp[i] 与 dp[i - 1] 之间的关联 -
从上述位运算进行演化
4. 代码实现
① 循环右移,位运算
class Solution {
public int[] countBits(int n) {
int[] ans = new int[n + 1];
for(int i = 0; i <= n; i++){
int t = i;
while(t > 0){
ans[i] += t & 1;
t = t >> 1;
}
}
return ans;
}
}
② 动态规划,dp[i] 与 dp[i >> 1]
class Solution {
public int[] countBits(int n) {
if(n == 0) return new int[]{0};
int[] dp = new int[n + 1];
dp[0] = 0;
dp[1] = 1;
for(int i = 1; i <= n; i++){
dp[i] = dp[i >> 1] + (i & 1);
}
return dp;
}
}