Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LeetCode题解:279. 完全平方数,动态规划,JavaScript,详细注释 #312

Open
chencl1986 opened this issue Mar 7, 2021 · 0 comments

Comments

@chencl1986
Copy link
Owner

原题链接:279. 完全平方数

解题思路:

  1. 本题类似于322. 零钱兑换,如果你对322. 零钱兑换不熟悉,可以先看题解。二者的区别是硬币种类不固定,在本题中,对于当前金额i,硬币种类为小于i的完全平方数。
  2. 该题递推的是从1开始,使用小于i完全平方数,计算能够凑到i的最小数量,由此不断累加到n的过程。
  3. 创建一个长度为n + 1dp数组,用索引就表示从0n的数字。
  4. 对于当前数字i,我们可以用for (let j = 1; j * j <= i; j++) {},计算出小于i的完全平方数。
  5. i是由i - j * j用1个j * j凑过来,同时要保证它是所有结果中最小的一个,因此状态转移返程为:dp[i] = Math.min(dp[i], dp[i - j * j] + 1);
/**
 * @param {number} n
 * @return {number}
 */
var numSquares = function (n) {
  // 需要计算到n,因此需要从0开始递推到n
  // 由于要计算的是最小值,因此初始化为Infinity,避免计算错误
  let dp = new Array(n + 1).fill(Infinity);
  dp[0] = 0; // 0对应的可组合数字为0

  // 从1开始才会有组合个数,一直递推到n
  for (let i = 1; i < dp.length; i++) {
    // 每次计算可用的完全平方数
    // 判断可用的方法是j*j不超过当前数量i
    for (let j = 1; j * j <= i; j++) {
      // 因为j * j <= i,所以i - j * j不可能小于0,无需判断
      dp[i] = Math.min(
        dp[i], // 当前已储存了之前完全平方数的组合数量
        // 当前的完全平方数数量,可由i - j * j加一个j * j而来
        // 因此等于dp[i - j * j]的数量加1个j * j
        dp[i - j * j] + 1,
      );
    }
  }

  // 递推到n时,就计算出了所有可能的数量
  return dp[n];
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant