题目
给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, ...)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。
示例 1:
输入: n = 12
输出: 3
解释: 12 = 4 + 4 + 4.
示例 2:
输入: n = 13
输出: 2
解释: 13 = 4 + 9.
动态规划四步走
1. 定义状态
2. 初始状态
3. 状态转移方程
4. 从dp[]中获取结果
具体到题目
定义状态
定义dp[i]为数字i的最小完全平方和的个数
初始状态
dp[0] = 1 ; dp[1] = 1
状态转移方程
定义变量k=1;对于数字i,如果 k+1是完全平方数,且k+1的平方为i,则dp[i] = 1 ,k自增;
否则,遍历1到k,dp[i] = 1+ dp[i-j * j]的最小值
if (k + 1) * (k + 1) === i
dp[i] = 1;
k++;
else
for( j: (1, k ))
dp[i] = Math.min(1 + dp[i - j * j])
完整代码
// @lc code=start
/**
* @param {number} n
* @return {number}
*/
var numSquares = function (n) {
if (n <= 0) {
return;
}
const dp = [];
dp[0] = 1;
dp[1] = 1;
let k = 1;
for (let i = 2; i <= n; i++) {
if ((k + 1) * (k + 1) === i) {
dp[i] = 1;
k++;
continue;
}
let min = i;
for (let j = 1; j <= k; j++) {
min = Math.min(min, 1 + dp[i - j * j]);
}
dp[i] = min;
}
console.log(dp);
return dp[n];
};
总结
题目还算比较简单,第一次的时候感觉只需要比较k和k-1即可,知道碰到48,此时k为6,而最优解为48=16+16+16,因此改为遍历1到k,感觉其中还可以优化,不需要遍历这么多。