[LeetCode] 0279.パーフェクトスクエア完全な方形

タイトル

正の整数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.

おすすめ

転載: www.cnblogs.com/bingmang/p/11408326.html