leetcode 673. 完全平方数

给定正整数 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)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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;
}
}

Author

Steven Zhu

Posted on

2020-04-24

Updated on

2023-07-08

Licensed under