279. 完全平方数

题目:

279. 完全平方数
在这里插入图片描述

题解:

1. 题解一:数学运算

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2. 题解二:动态规划

在这里插入图片描述
在这里插入图片描述

n = 12
先把 n 减去一个平方数,然后求剩下的数分解成平方数和所需的最小个数

把 n 减去 1, 然后求出 11 分解成平方数和所需的最小个数,记做 n1
那么当前方案总共需要 n1 + 1 个平方数

把 n 减去 4, 然后求出 8 分解成平方数和所需的最小个数,记做 n2
那么当前方案总共需要 n2 + 1 个平方数

把 n 减去 9, 然后求出 3 分解成平方数和所需的最小个数,记做 n3
那么当前方案总共需要 n3 + 1 个平方数

下一个平方数是 16, 大于 12, 不能再分了。

接下来我们只需要从 (n1 + 1), (n2 + 1), (n3 + 1) 三种方案中选择最小的个数, 
此时就是 12 分解成平方数和所需的最小个数了

至于求 1183 分解成最小平方数和所需的最小个数继续用上边的方法去求

直到如果求 0 分解成最小平方数的和的个数, 返回 0 即可

代码:

1. 代码一:数学运算

import java.util.*;

public class code279 {
    
    // 判断是否是[完全]平方数
    public static boolean isSquare(int n) 
    {
        int sqrt = (int) Math.sqrt(n);
        return sqrt * sqrt == n;
    }
    
    public static int numSquares(int n) 
    {
        // 判断答案是否是 1
        if(isSquare(n))
        {
            return 1;
        }

        // 判断答案是否是 4
        int temp = n;
        while(temp % 4 == 0)
        {
            temp /= 4;
        }
        if(temp % 8 == 7)
        {
            return 4;
        }

        // 判断答案是否是 2
        for(int i = 1; i * i <= n; i++)
        {
            if(isSquare(n - i * i))
            {
                return 2;
            }
        }
        // 以上情况都排除的话,答案就是 3
        return 3;
    }
    
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while(sc.hasNextInt()) 
        {
            int n = sc.nextInt();
            int res = numSquares(n);
            System.out.println(res);
        }        
    }
}

2. 代码二:动态规划

import java.util.*;

public class code279 {

    // 方法2:动态规划
    public static int numSquares(int n) {
        // dp[i]表示 i 最少可以由几个[完全]平方数构成
        int dp[] = new int[n + 1]; // 默认初始化值都为0
        dp[0] = 0;
        for(int i = 1; i <= n; i++)
        {
            dp[i] = i; // 最坏的情况就是每次+1
        }        
        // 依次求出 1, 2... 直到 n 的解
        for(int i = 1; i <= n; i++)
        {
            // 依次减去一个[完全]平方数
            for(int j = 1; j * j <= i; j++)
            {
                dp[i] = Math.min(dp[i], dp[i - j * j] + 1); // 动态转移方程
            }
        }
        return dp[n];
    }
    
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while(sc.hasNextInt()) 
        {
            int n = sc.nextInt();
            int res = numSquares(n);
            System.out.println(res);
        }        
    }
}

参考:

  1. 详细通俗的思路分析,多解法
  2. 完全平方数
  3. 画解算法:279. 完全平方数
  4. python3最基础的BFS套路代码,适合入门新手!
  5. 【超直白】【靠嘴讲】小学生都能看懂的题解,还看不懂我打你~
  6. 动态规划+BFS 逐行解释 python3
  7. 不只是答案,而是动态规划类题的思考过程
  8. Java 解法:将问题转化为图论

附:

递归、记忆化搜索、动态规划之间的联系:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dev_zyx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值