Leetcode279:完全平方数(Perfect Squares)
给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, …)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。
示例 1:
输入: n = 12
输出: 3
解释: 12 = 4 + 4 + 4
.
示例 2:
输入: n = 13
输出: 2
解释: 13 = 4 + 9.
示例 1:
思考
当n=12时:
n=1+11 or n=4+8 or n=9+3
当n=13时:
n=1+12 or n=4+9 or n=9+4
可以看出所输入的n,可以表示成一个完全平方数加上另一个数,所以只要计算另一个数所需的完全平方数的最小个数,然后再加上1,就是n所需的完全平方数的最小个数。
递推关系式
那些本身就是完全平方数,所需的完全平方数的个数为1,而其他本身不是完全平方数的数,就是1这个完全平方数开始,m[1]+m[n-1],m[4]+m[n-4],m[9]+m[n-9],m[16]+m[n-16],以此类推,这里的m[i]指的是n为i时,所需的完全平方数的最小个数,因此只要算min(m[1]+m[n-1],m[4]+m[n-4],m[9]+m[n-9],m[16]+m[n-16] …等),因此递推关系式如下:
min(b,m[j*j]+m[a])
代码如下
#include <iostream>
using namespace std;
class Solution {
private:
int min(int a,int b){
if(a>b)
return b;
else
return a;
}
public:
int numSquares(int n) {
long long a,b=100000;//用b来存储最小个数,然后赋给m[i],b的值尽可能大点
long long i=1,j;
int m[10000]={0} //用数组m来记录n为i时,所需的完全平方数的最小个数
while(i*i<n)
{
m[i*i]=1;
i++;
}
if(i*i==n)
{
return 1;
}
else
{
for(i=1;i<=n;i++)
{
for(j=1;j*j<=i;j++)
{
a=i-j*j;
b=min(b,m[j*j]+m[a]);
}
m[i]=b;
b=100000;
}
return m[n];
}
}
};
总结
初学动态规划,感觉有点难度,这题也是想了有一会,估计代码还有能改进的地方,请大家多多包涵,也可以指出不足之处。