动态规划
动态规划思路:
- 状态定义:定义一个一维数组dp,其中
dp[i]表示组成整数i所需的最少完全平方数的数量
。- 状态初始化:将
dp数组中的所有元素初始化为Integer.MAX_VALUE
,表示初始状态下组成每个整数的完全平方数数量是无限大(即不可能)。但dp[0]需要初始化为0,因为组成整数0不需要任何完全平方数
。- 状态转移:遍历所有可能的完全平方数,对于每个完全平方数square[i],更新dp数组。具体来说,对于当前完全平方数square[i],遍历所有从square[i]到n的整数,更新dp[j]的值。如果dp[j - square[i]]不是Integer.MAX_VALUE(即j - square[i]这个整数是可以凑出的),则更新
dp[j]为min(dp[j - square[i]] + 1, dp[j])
。- 返回结果:最后,返回dp[n],即组成整数n所需的最少完全平方数的数量。
本人版本
class Solution {
public int numSquares(int n) {
int[] dp = new int[n + 1];
int[] square = new int[100];
for(int i = 0; i < square.length; i++){
square[i] = (i + 1) * (i + 1);
}
// 初始状态下组成每个整数的完全平方数数量是无限大(即不可能)
for (int j = 0; j <= n; j++) {
dp[j] = Integer.MAX_VALUE;
}
dp[0] = 0;
for(int i = 0; i < square.length; i++){
for(int j = square[i]; j <= n; j++){
dp[j] = Math.min(dp[j - square[i]] + 1, dp[j]);
}
}
return dp[n];
}
}
代码简化版本
class Solution {
public int numSquares(int n) {
int[] dp = new int[n + 1];
for (int j = 0; j <= n; j++) {
dp[j] = Integer.MAX_VALUE;
}
dp[0] = 0;
for(int i = 1; i * i <= n; i++){
for(int j = i * i; j <= n; j++){
dp[j] = Math.min(dp[j - i * i] + 1, dp[j]);
}
}
return dp[n];
}
}