leetcode_middle_68_279. Perfect Squares

本文探讨了一道数学问题的高效解决方案:寻找构成给定整数所需的最小数量的平方数之和。通过对比广度优先搜索与动态规划两种方法,详细解释了如何利用动态规划思想简化问题并提供了一个简洁的实现示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:

给定一个数,找出最少多少个平方数(可以重复)之和为这个数。


分析:

这个题就是一个搜索题,由于是找个数,第一想法就是广度优先搜索。程序正确但是无奈超时。

public class Solution {
    public int numSquares(int n) {
        //广度优先搜索
        int res = 0;
        Queue<Integer> q = new LinkedList<>();
        q.offer(n);
        while(!q.isEmpty()){
            int size = q.size();
            res++;
            for(int i=0; i<size; i++){
                int num = q.poll();
                for(int k=1; k<=(int)Math.sqrt(n); k++){
                    if(num - k*k > 0){
                        q.offer(num - k*k);
                    }else if(num - k*k == 0){
                        return res;
                    }
                }
            }
        }
        return res;
    }
}

基本上深搜广搜要超时的解决办法就是动态规划。

我们举例子分析问题:1   2    3   4      5      6     7    8      9      10      11       12       13

具体对应的值就不写上来了,但是我们发现比如dp[7] = dp[6] + 1  ,对于12   问题来了:4+4+4  其实就是dp[ 8 ] + 1

所以其实就很简单了:  dp的动态联系在于  dp[ j ]  =   dp[ j - i* i ] +1

其实我觉得理解了深搜广搜本质(搜索树)的,动态规划非常简单,因为思路本质上是一样的。

比如12 我们广搜:

第一层要分成:12-1        12- 4       12 - 9

dp其实一模一样,就是用了一个记录结果的数组正向推起来。

dp[12]   就是     dp[11 ] +1       dp[ 8]  +1         dp[3]  +1

public class Solution {
    public int numSquares(int n) {
        int[] dp = new int[n + 1];
        
        for(int i = 1; i <= n; i++) {
            int min = Integer.MAX_VALUE;
            for(int j = 1; j * j <= i; j++) {
               min = Math.min(min, dp[i - j*j] + 1);
            }
            dp[i] = min;
        }
        return dp[n];
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值