Given a positive integer n, find the least number of perfect square numbers (for example, 1, 4, 9, 16, ...
) which sum to n.
Example 1:
Input: n = 12
Output: 3
Explanation: 12 = 4 + 4 + 4.
Example 2:
Input: n = 13
Output: 2
Explanation: 13 = 4 + 9.
题意:求给出的数最少能由几个数的平方和组成。
思路:给出一个数x(x=y^2+z),求它的最少数量的平方和,此时若z的最少数量的平方和已经求出,则x的最少数量的平方和=z的最少数量的平方和+1;
例如x=13,当y=1时,z=12,由给出的示例可知 leastNums[12]=3,所以leastNums[13]=leastNums[12]+1 = 4;
当y=2时,z=9,9=3*3,所以 leastNums[9]=1,leastNums[13]=leastNums[9]+1 = 2;
当y=3时,z=4,4=2*2,所以 leastNums[4]=1,leastNums[13]=leastNums[4]+1 = 2。
使用动态规划的方法, 从1开始一直到n,算出每个数至少能由几个数的平方和组成。
代码:
class Solution {
public int numSquares(int n) {
if(n<=0)
return 0;
int[] leastNums = new int[n+1];
leastNums[0]=0; //x=y*y+z,若z=0,则leastNums[x]=leastNums[0]+1
for(int i =1;i<=n;i++){
int minNum = Integer.MAX_VALUE; //默认值为INT最大值
for(int j=1;j*j<=i;j++){
//leastNums[x]=leastNums[z]+1
minNum = Math.min(minNum,leastNums[i - j*j]+1);
}
leastNums[i] = minNum;
}
return leastNums[n];
}
}
还有一种用数学公式求的方法(c++):
class Solution
{
private:
int is_square(int n)
{
int sqrt_n = (int)(sqrt(n));
return (sqrt_n*sqrt_n == n);
}
public:
// Based on Lagrange's Four Square theorem, there
// are only 4 possible results: 1, 2, 3, 4.
int numSquares(int n)
{
// If n is a perfect square, return 1.
if(is_square(n))
{
return 1;
}
// The result is 4 if and only if n can be written in the
// form of 4^k*(8*m + 7). Please refer to
// Legendre's three-square theorem.
while ((n & 3) == 0) // n%4 == 0
{
n >>= 2;
}
if ((n & 7) == 7) // n%8 == 7
{
return 4;
}
// Check whether 2 is the result.
int sqrt_n = (int)(sqrt(n));
for(int i = 1; i <= sqrt_n; i++)
{
if (is_square(n - i*i))
{
return 2;
}
}
return 3;
}
};