给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, …)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。
示例 1:
输入: n = 12
输出: 3
解释: 12 = 4 + 4 + 4.
示例 2:
输入: n = 13
输出: 2
解释: 13 = 4 + 9.
法1: 动态规划,时间复杂度O(n*sqrt(n)), 空间复杂度O(n)
class Solution {
public:
int numSquares(int n) {
vector<int> dp(n+1, 0);
vector<int> mults;
int i = 1;
while(i*i <= n) {
mults.push_back(i*i);
i++;
}
for (int i = 1; i <= n; i++)
{
int min_nums = i+1;
for (int j = 0; j < mults.size() && i >= mults[j]; j++)
{
min_nums = min(min_nums, dp[i - mults[j]] + 1 );
}
dp[i] = min_nums;
}
return dp[n];
}
};
法2:数学方法, 时间复杂度:O(sqrt(n)), 空间复杂度O(1).
class Solution {
protected boolean isSquare(int n) {
int sq = (int) Math.sqrt(n);
return n == sq * sq;
}
public int numSquares(int n) {
// four-square and three-square theorems.
while (n % 4 == 0)
n /= 4;
if (n % 8 == 7)
return 4;
if (this.isSquare(n))
return 1;
// enumeration to check if the number can be decomposed into sum of two squares.
for (int i = 1; i * i <= n; ++i) {
if (this.isSquare(n - i * i))
return 2;
}
// bottom case of three-square theorem.
return 3;
}
}