leetcode题解279-完全平方数
发布日期:2025-04-05 05:40:41 浏览次数:8 分类:精选文章

本文共 1174 字,大约阅读时间需要 3 分钟。

问题描述:给定一个正整数n,我们需要找到若干个完全平方数,使它们的和等于n,并使得到达和的完全平方数的个数最少。例如,n=12时,可以是4+4+4,总共有3个平方数。

提示:完全平方数是指某个整数的平方,例如1,4,9,16等。给定n的取值范围是在1到104之间。

解题思路:这次问题可以使用动态规划技术来解决。动态规划是一种通过重用中间计算结果来高效地解决问题的方法。我们可以将问题分解为更小的子问题,并保存已经计算出的子问题的解,以便快速解决当前问题。

关键点:

  • 初始化dp数组:创建一个长度为n+1的数组dp,初始化时每个位置的值设为i。这样,在最坏的情况下,i只能是i个1相加,例如n=4时,最坏情况是需要4个1相加。
  • 动态转移方程:对于每个数字i,我们从i开始减去一个平方数j²,检查剩下的部分i-j²是否有解。如果有解,那么最少平方数的个数就是dp[i-j²] + 1。我们需要找到最小的平方数的个数,因此每次更新dp[i]为当前dp[i]和新值中的较小者。
  • 计算过程:从1到n依次处理每个i,使用上述动态转移方程更新dp数组。
  • 最终,dp[n]将保存使n为多个完全平方数之和的最小个数。
  • 代码实现:

    public class Solution {    public int numSquares(int n) {        int dp[] = new int[n + 1];        for (int i = 1; i <= n; i++) {            dp[i] = i; // 最坏情况下,每个数都是1            for (int j = 0; i - j * j >= 0; j++) {                dp[i] = Math.min(dp[i], dp[i - j * j] + 1);            }        }        return dp[n];    }}

    解释:

    • 初始化:dp数组从1到n初始化为i,这是因为在没有找到更优解的情况下,我们假设需要i个1。

    • 动态转移:对于每个i,从1到n,我们检查从i开始减去j²(j从0开始,j大的平方数尽量大),更新dp[i]为当前最小的平方数个数。每次尝试减去一个平方数后,剩余部分i-j²的值已经在dp中计算过,因此可以快速得到解。

    • 高效性:通过递归地减少问题规模,我们避免了递归可能带来的堆栈溢出问题,并且能够显著减少计算量。每个数字i只需要检查到sqrt(i)的平方数j²,时间复杂度为O(n√n),在n=104的情况下非常高效。

    • 结果:dp[n]将包含由最少完全平方数之和等于n的个数。

    该方法利用动态规划技术有效地解决了问题,最少平方数之和的问题得到了优化,并通过示例验证了其准确性和效率。

    上一篇:leetcode题解3-无重复字符的最长子串
    下一篇:leetcode题解26-删除数组的重复项

    发表评论

    最新留言

    感谢大佬
    [***.8.128.20]2025年04月24日 12时02分31秒

    关于作者

        喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
    -- 愿君每日到此一游!

    推荐文章