leetcode 链接:279. 完全平方数

题目

给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, ...)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。
给你一个整数 n ,返回和为 n 的完全平方数的 最少数量

完全平方数 是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,14916 都是完全平方数,而 311 不是。

示例:

  1. 输入:n = 12
  2. 输出:3
  3. 解释:12 = 4 + 4 + 4
输入:n = 13
输出:2
解释:13 = 4 + 9

解答 & 代码

动态规划(完全背包问题):

  • dp 数组,dp[i] 代表和为 i 的完全平方数的最少数量
  • 状态转移:dp[i] = min(dp[i - k] + 1),其中 k 是完全平方数,且 1 <= k <= i。即(内循环)遍历最后一一个可能用的完全平方数取值 kdp[i - k] + 1 是最后一个数取 k 所需的完全平方数的最小数量
    • 外层循环 target(即目标和 1~n)
    • 内层循环平方数,即 1,4, 9…
  • 初始化:dp[0] = 0

    class Solution {
    public:
      int numSquares(int n) {
          // dp 数组,dp[i] 代表和为 n 的完全平方数的最少数量 
          vector<int> dp(n + 1, INT_MAX);
          dp[0] = 0;    // 初始化
          for(int i = 1; i <= n; ++i)            // 外层循环 target
          {
              for(int j = 1; j * j <= i; ++j)    // 内存循环平方数
                  dp[i] = min(dp[i], dp[i - j * j] + 1);
          }
          return dp[n];
      }
    };
    

    复杂度分析:

  • 时间复杂度 [中等] 279. 完全平方数 - 图1

  • 空间复杂度 O(n)

执行结果:

执行结果:通过

执行用时:172 ms, 在所有 C++ 提交中击败了 58.58% 的用户
内存消耗:8.9 MB, 在所有 C++ 提交中击败了 40.52% 的用户