标题:279. 完全平方数
难度:中等
天数:第21天,第3/3题
给你一个整数
n
,返回 和为n
的完全平方数的最少数量 。
完全平方数 是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,
1
、4
、9
和16
都是完全平方数,而3
和11
不是。
示例 1:
输入:n =
12
输出:3
解释:12 = 4 + 4 + 4
示例 2:
输入:n =
13
输出:2
解释:13 = 4 + 9
提示:
1 <= n <= 104
以上来源:力扣(LeetCode)
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题解:
一.分析问题
dp[n] 存放到n的最少数量
我们将正数n理解成背包容量
平方数理解成重量,那就是一个完全背包问题
我们要求解最少数量,那么为了能够通过Math。函数统计最小数量,我们将dp[n]每一个值都初始化成最大值Integer.MAX_VALUE
int max = Integer.MAX_VALUE;
for(int i = 0;i <=n;i++){
dp[i] = max;
}
外层循环背包容量
for(int i = 1 ; i <= n; i++){}
内层循环物品重量
//内层物品
for(int j = 1; j * j <= i;j++){}
确定动态规划方程:
我们应该对比dp[n]
的值,和当前值 - k
重量位置记录的值 + 1
两个数中哪个方式装满背包用的数量最小
也就是
dp[n] = Math.min(dp[n], dp[n-k] + 1);
这里的k转换成循环就是对应的j*j
dp[n] = Math.min(dp[n], dp[n - j*j] + 1);
最后根据动归方程,分析下初始化值dp[0]
如果 n = 1
dp[1] = Math.min(max,dp[0] + 1);
可以推断出,我们应该将dp[0]
初始化成0
,dp[0] = 0
;。
class Solution {
//动态规划 第21天 3/3
//完全背包问题
public int numSquares(int n) {
int max = Integer.MAX_VALUE;
int[] dp = new int[n+1];
for(int i = 0;i <=n;i++){
dp[i] = max;
}
dp[0] = 0;
//外层背包 容量
for(int i = 1 ; i <= n; i++){
//内层物品重量k = j*j
for(int j = 1; j * j <= i;j++){
dp[i] = Math.min(dp[i], dp[i - j*j] +1);
}
}
return dp[n];
}
}