LeetCode - 279. 完全平方数

279. 完全平方数

给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, …)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。
在这里插入图片描述
解题思路: 此题有两种解法,即BFS和DP。先说BFS的解法,我们可以把完全平方数与它的分解的平方数看成一个图,确切的说看成一个多叉树,然后题目要求我们求组成完全平方数最少,那我们可以转化为找最短的一条路径,那我们自然会想到找迷宫的题,因此使用BFS最为合适,思路也比较直接和简单。请看代码。

  1. 解法一
class Solution {
public:
    int numSquares(int n) {
        if (n == 1) return 1;
        int a = sqrt(n);
        queue<int> q{{n}};
        int res = 0;
        while (!q.empty()) {
            for (int i = q.size(); i > 0; --i) {
                int tmp = q.front(); q.pop();
                if (tmp == 0) return res;
                for (int j = sqrt(tmp); j >= 1; --j) {
                    q.push(tmp - j * j);
                }
            }
            ++res;
        }
        return res;
    }
};

其实这题我们也可以用动态规划解题。解动态规划的题的关键是找到动态转移方程,这题的动态转移方程是: d p ( i ) = m i n ( d p ( i − 1 2 ) , d p ( i − 2 2 ) , . . . , d p ( i − j 2 ) dp(i)=min(dp(i-1^2),dp(i-2^2),...,dp(i-j^2) dp(i)=min(dp(i12),dp(i22),...,dp(ij2),其中 j 2 j^2 j2为最接近i的完全平方数。基本上到这里此题就可解了。

  1. 解法二
class Solution {
public:
    int numSquares(int n) {
        vector<int> dp(n + 1);
        for (int i = 1; i <= n; ++i) dp[i] = i;
        for (int i = 1; i <= n; ++i) {
            int mn = INT_MAX;
            for (int j = sqrt(i); j >= 1; --j) {
                mn = min(mn, dp[i - j * j]);
            }
            dp[i] = mn + 1;
        }
        return dp[n];
    }
};

*动态规划+最优解的Tips:
这里在提一个动态规划解题的感受。解动态规划的题,尤其是解那个含最优解的题,比如这里取最小值(含比较大小),我们的每个节点的值并不是一开始就确定为最优值的,往往一开始赋的都是不太优的值,然后在遍历的过程中一遍一遍刷新所有节点的值,在这个刷新的过程中,所有的节点值会慢慢变为最优解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值