タイトル
正の整数nを与え、合計n個の完全平方数の最小数(例えば、1、4、9、16、...)を見つけます。
完全平方数を見つけるために、正の整数nを与えられた(例えば、1、4、9、16、...)となるようNに等しいその合計。少なくとも、あなたは数と組成の完全な方形を作成する必要があります。
例1:
Input: n = 12
Output: 3
Explanation: 12 = 4 + 4 + 4.
例2:
Input: n = 13
Output: 2
Explanation: 13 = 4 + 9.
ソリューション
遅くソリューションであり、動的プログラミングは、現在、主にBFSのタイトルをやって、ピットを維持します。
class Solution {
public:
int numSquares(int n) {
if (n == 0) {
return 0;
}
vector<int> steps(n + 1, INT_MAX);
steps[0] = 0;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j * j <= i; ++j) {
steps[i] = min(steps[i], steps[i - j * j] + 1);
}
}
return steps[n];
}
};
ソリューション2
最短経路、BFS
参考:https://blog.csdn.net/qq_17550379/article/details/80875782
アイデア:まあ、最短経路を見つける確かに幅優先探索を使用し、デジタル・キューを解体続けるが、その答えは、最短パスを取得した後に直接返されます。具体的なアプローチは、以下の特定BFSのアイデアです、非常に簡単です:
還元ならば、プッシュキューN、および減算後の0に等しくない場合、残りの値によって、(-1、-4、-9 ...)を解体取り出しは、検索の第二ラウンドを待って、キューをプッシュします秋には直接答えを見つける0に等しいた後、あなたはもう検索する必要はありません、+ 1のステップに戻ることができます(それがサイクル図であるので、アウンを訪問したことを忘れないでください)。
class Solution {
public:
int numSquares(int n) {
queue<pair<int, int>> q;
// pair.first 代表将n拆解后的数字,pair.second代表所走的步数
// 刚开始推入未拆解的n,步数为0
q.push(make_pair(n, 0));
bool visited[n + 1];
memset(visited, 0, sizeof(visited));
visited[n] = true;
// 开始广度优先搜索
while (!q.empty()) {
// 取队头,进行拆解
auto pair = q.front();
q.pop();
int i = 1;
int next_num = pair.first - i * i;
// 在推入队列前先看看能不能解答
while (next_num >= 0) {
if (next_num == 0) {
return pair.second + 1;
}
// 还有余数没扣完,就将可以的下一步都推入队列
if (!visited[next_num]) {
q.push(make_pair(next_num, pair.second + 1));
visited[next_num] = true;
}
// 计算下一步
i++;
next_num = pair.first - i * i;
}
}
return 0;
}
};
結果:
Runtime: 16 ms, faster than 86.01% of C++ online submissions for Perfect Squares.
Memory Usage: 11.6 MB, less than 24.62% of C++ online submissions for Perfect Squares.
ソリューション3
ラグランジュ4つの平方定理:任意の正の整数は、4つの整数の二乗の和を超えないように表すことができます。推論:数満たすN(4つの整数)4番及び正方形定理、満足しなければならないN = 4 ^ A(8B + 7)。
あなたは、1つのまたは2つの完璧な正方形ことができない場合は、この定理はこの質問への答えはただ1以上のもので、2ではないことを教えてくれるし、上記の式を満たしていれば、その答えは4である、優れたコンピュータの数学を持っていますか組成物は、次に3を返します。
(本当に暴力的、ああ、逃れるために......
class Solution {
public:
int numSquares(int n) {
// Lagrange四平方定理:任何一个正整数都可以表示成不超过四个整数的平方之和。
// 推论:满足四数平方和定理的数n(四个整数的情况),必定满足 n=4^a(8b+7)。
while (n % 4 == 0)
n /= 4;
if (n % 8 == 7)
return 4;
int a = 0;
while (a * a <= n) {
int b = (int)sqrt(n - a * a);
if (a * a + b * b == n) {
return (a ==0 || b == 0) ? 1 : 2;
}
a++;
}
return 3;
}
};
結果:
Runtime: 0 ms, faster than 100.00% of C++ online submissions for Perfect Squares.
Memory Usage: 8.4 MB, less than 90.15% of C++ online submissions for Perfect Squares.