问题
给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, …)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。
例子
思路
-
方法1
dp
res[i]为,相加得到正整数i的最小完全平方数的个数:
r e s [ i ] = r e s [ i − j ] + r e s [ j ] res[i]=res[i-j]+res[j] res[i]=res[i−j]+res[j]
没有利用好条件的特性 -
方法2
dp
res[i]由于都是完全平方数相加得到,
r e s [ i ] = r e s [ i − j ∗ j ] + r e s [ j ∗ j ] = r e s [ i − j ] + 1 res[i]=res[i-j*j]+res[j*j]=res[i-j]+1 res[i]=res[i−j∗j]+res[j∗j]=res[i−j]+1
比较的次数大大降低,对于得到res[i],方法1的次数为i/2,方法2为 i \sqrt{i} i
代码
//方法1
class Solution {
public int numSquares(int n) {
if(n==1) return 1;
int[] res = new int[n+1];
res[1]=1;
for(int i=2; i<=n; i++) {
int t = (int)Math.sqrt(i);
if(t*t==i) res[i]=1;
else{
int min = Integer.MAX_VALUE;
for(int j=i-1; j>=i/2; j--) {
int tt = res[j]+res[i-j];
min=Math.min(min, tt);
}
res[i]=min;
}
}
return res[n];
}
}
//方法2
class Solution {
public int numSquares(int n) {
int[] res = new int[n+1];
for(int i=1; i<=n; i++) {
int min = Integer.MAX_VALUE;
for(int j=1; j*j<=i; j++)
min=Math.min(min, res[i-j*j]+1);
res[i]=min;
}
return res[n];
}
}