[LeetCode] 0279. Perfect Squares 完全平方数

题目

Given a positive integer n, find the least number of perfect square numbers (for example, 1, 4, 9, 16, ...) which sum to n.

给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, ...)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。

Example 1:

Input: n = 12
Output: 3 
Explanation: 12 = 4 + 4 + 4.

Example 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];
    }
};

解法二

最短路径,BFS

参考资料:https://blog.csdn.net/qq_17550379/article/details/80875782

思路:寻找最短路径嘛,肯定是用到广度优先搜索了,不断拆解队列中的数字,得到答案后直接返回就是最短路径了。具体的做法很简单,以下是具体BFS思路:

把n推入队列,然后取出来进行拆解(-1,-4,-9…),减掉后如果不等于0,就将余下来的值推入队列,等待第二轮搜索,如果减掉后等于0就是直接找到答案了,返回step+1即可,不需要再搜索下去了(记得要有visited昂,因为是个循环图)。

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.

解法三

Lagrange四平方定理:任何一个正整数都可以表示成不超过四个整数的平方之和。 推论:满足四数平方和定理的数n(四个整数的情况),必定满足 n=4^a(8b+7)。

做计算机的数学也要好啊,这个定理告诉我们,这道题的答案无非只有1、2、3、4,而且如果满足上述公式,那么答案就是4,如果不能被1个或2个完全平方数组成,那么就返回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.

转载于:https://www.cnblogs.com/bingmang/p/11408326.html

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看READme.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值