给一个正整数 n, 找到若干个完全平方数(比如1, 4, 9, ... )使得他们的和等于 n。你需要让平方数的个数最少。
样例
给出 n = 12
, 返回 3
因为 12 = 4 + 4 + 4
。
给出 n = 13
, 返回 2
因为 13 = 4 + 9
。
解题思路1:
状态:设dp[i]表示和为i的最小完全平方个数
最后一步:关注最优策略中最后一个完全平方数j^2,则最优策略中i-j^2也一定被划分成最小的完全平方个数
状态方程:dp[i] = min(dp[i], dp[i - j * j] + 1), j * j <=i
初始化:dp[i] = i,因为对于和为i最多有i个平方和且每个平方都是1
public class Solution {
/**
* @param n: a positive integer
* @return: An integer
*/
public int numSquares(int n) {
// write your code here
int[] dp = new int[n + 1];
for (int i = 0; i <= n; i++) {
dp[i] = i; // max square number is i itself with all 1
for (int j = 1; j * j <= i; j++)
if (dp[i] > dp[i - j * j] + 1)
dp[i] = dp[i - j * j] + 1;
}
return dp[n];
}
}
解题思路2:
状态:设dp[i]表示和为i的最小完全平方个数
初始化:当i就是完全平方数时,dp[i]=1,其他情况dp[i] = i,因为对于和为i最多有i个平方和且每个平方都是1
状态方程:dp[i] = min(dp[i], dp[j] + dp[i-j]),j<i,因为j+i-j=i
public class Solution {
/**
* @param n: a positive integer
* @return: An integer
*/
public int numSquares(int n) {
// write your code here
int[] dp = new int[n+1];
for(int i=1; i<=n; i++){
if(isSquare(i)){
dp[i] = 1;
continue;
}
dp[i] = i;
for(int j=1; j<i; j++)
dp[i] = Math.min(dp[i], dp[j]+dp[i-j]);
}
return dp[n];
}
private boolean isSquare(int num){
double tmp = Math.sqrt(num);
int tmp1 = (int)tmp;
if(tmp - tmp1 == 0)
return true;
return false;
}
}