题目:
Given a positive integer n, find the least number of perfect square numbers (for example, 1, 4, 9, 16, ...
) which sum to n.
For example, given n = 12
, return 3
because 12 = 4 + 4 + 4
; given n = 13
, return 2
because 13 = 4 + 9
.
解答:
很明显的dp,最终的复杂度应该是n^(3/2)
class Solution {
public:
int numSquares(int n) {
vector<int> dp(n + 1, 1);
dp[0] = 0;
for(int i = 2;i <= n; ++i)
{
int tmp = INT_MAX;
for(int j = 1; j * j <= i; ++j)
{
if(dp[i - j * j] + 1 < tmp)
tmp = dp[i - j * j] + 1;
}
dp[i] = tmp;
}
return dp[n];
}
};
plus:
看到有人用纯数学的方法也是可以解这道题目的,代码如下:
利用的原理是:每个正数都可以被分解为4个平方数的和,如果这个数字符合4^t * (8k + 7)的形式,则可以被三个平方数的和表示....(参考leetcode讨论区)点击打开链接不过这种方法其实没什么意思,不属于计算机的思维了
class Solution {
public:
int numSquares(int n) {
while (n % 4 == 0) n /= 4;
if (n % 8 == 7) return 4;
int m = sqrt(n);
if (m * m == n) return 1;
if (n % 2 == 0) n >>= 1;
if (n % 4 == 3) return 3;
for (int i = 3; i * i < n; i += 4)
if (n % i == 0) {
bool odd = true;
n /= i;
while (n % i == 0) {
odd = !odd;
n /= i;
}
if (odd) return 3;
}
return 2;
}
};