【动态规划】LeetCode 338. 比特位计数-Medium

279 阅读1分钟

题目

给定一个非负整数 num。对于 0 ≤ i ≤ num 范围中的每个数字 i ,计算其二进制数中的 1 的数目并将它们作为数组返回。

示例 1:

输入: 2
输出: [0,1,1]

示例 2:

输入: 5
输出: [0,1,1,2,1,2]

动态规划四步走

1. 定义状态
2. 初始状态
3. 状态转移方程
4. 从dp[]中获取结果

具体到题目

定义状态

定义dp[i]为数字i中的 1 的数目

初始状态

dp[0] = 0

状态转移方程

自底向上分析得出,需要一个标记位为2的k次方,当i为这个数时,dp[i]=1;否则 dp[n]=dp[i-2^(k-1)]+1

从dp[]中获取结果

dp数组就是最后的结果

完整代码

// @lc code=start
/**
 * @param {number} num
 * @return {number[]}
 */
var countBits = function (num) {
  if (typeof num !== 'number' || num < 0) {
    return;
  }
  const dp = [];
  dp[0] = 0;
  let k = 0;
  let z = Math.pow(2, k);
  let y = z;
  for (let i = 1; i <= num; i++) {
    if (i === z) {
      dp[i] = 1;
      y = z;
      k++;
      z = Math.pow(2, k);
    } else {
      dp[i] = dp[i - y] + 1;
    }
  }
  console.log(dp);
  return dp;
};

countBits(100);

总结

还是一道慢慢分析就能分析出来的题目,需要注意的是这里不是单纯的找dp[n]和dp[n-1]的关系