• 279.完全平方数


    完全平方数

    给你一个整数 n ,返回 和为 n 的完全平方数的最少数量 。

    完全平方数 是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,1、4、9 和 16 都是完全平方数,而 3 和 11 不是。

    示例 1:

    输入:n = 12
    输出:3
    解释:12 = 4 + 4 + 4
    示例 2:

    输入:n = 13
    输出:2
    解释:13 = 4 + 9

    提示:

    1 <= n <= 104

    思考

    这一题我觉得其实比我做的上一题 322. 零钱兑换 更加简单,

    因为这个没有不存在的情况,因为有万能1的存在,怎么凑都可以凑够!

    我认为这个只是多出一步需要自己求出,n以内的完全平方数,就可以转换成一个和322. 零钱兑换类似的问题,并且更简单考虑的情况更少!

    首先第一个问题,我们如何求n以内完全平方数

          // step 0 求n以内的完全平方数
            int[] square=new int[n/2];
            int l=1;
            square[0] = 1;
            for (int i=2;i<n;i++){
                if(i*i>n) break;
                square[i-1] = i*i;
                l++;
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    解下来就转化成了01背包问题,假设n=12,其完全平方数数组为x={1,2,4,9}

    其实也就是用{1,2,4,9}里面最少的数去凑满12即可!

    定义dp数组及其下标含义

    dp[j] : 表示使用了完全平方数组去凑满j使用的完全平方数的最少个数

    初始化dp数组

    dp[0]=0; 保证 dp[j-x[i]] x[i]==j时 dp[j] = 1;

    dp[1]=1;

    其余dp[j] = Integer.Max;

    状态转移方程

    遍历x,选择最小的dp[j] = dp[j - x[i]]

    public int numSquares(int n) {
            // step 0 求n以内的完全平方数
            int[] square=new int[n/2];
            int l=1;
            square[0] = 1;
            for (int i=2;i<n;i++){
                if(i*i>n) break;
                square[i-1] = i*i;
                l++;
            }
            if(l<=1) return n;
    
            // step 2 创建dp数组
            int[] dp=new int[n+1];
    
            // step 3 初始化dp数组
            dp[0]=0;
            dp[1]=1;
            for (int i=2;i<dp.length;i++){
                dp[i] =Integer.MAX_VALUE;
            }
    
            // step 4 完善dp数组
            for (int j=2;j<dp.length;j++){
                for (int num : square){
                    if(num<=j){
                        dp[j]=Math.min(dp[j],dp[j-num]+1);
                    }
                }
            }
    
            // print Dp
            for (int i=0;i<dp.length;i++){
                System.out.println("dp "+i+","+dp[i]);
            }
            return dp[dp.length-1];
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    进阶

    其获取>n的完全平方数,完全可以在循环中进行

        public int numSquares2(int n) {
            
    
    
            // step 2 创建dp数组
            int[] dp=new int[n+1];
    
            // step 3 初始化dp数组
            dp[0]=0;
            dp[1]=1;
            for (int i=2;i<dp.length;i++){
                dp[i] =Integer.MAX_VALUE;
            }
    
            // step 4 完善dp数组
            for (int j=2;j<dp.length;j++){
            //step 0 求n以内的完全平方数
                for (int i=1;i*i<=j;i++){
                    int num=i*i;
                    if(num<=j){
                        dp[j]=Math.min(dp[j],dp[j-num]+1);
                    }
                }
            }
    
            // step 5 print Dp
            for (int i=0;i<dp.length;i++){
                System.out.println("dp "+i+","+dp[i]);
            }
            return dp[dp.length-1];
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
  • 相关阅读:
    七牛云 OSS 文件上传demo
    pytorch、tensorflow对比学习—张量
    【LeetCode】1224. 最大相等频率
    vue项目的环境准备与创建详情
    Windows查看所有的端口
    Prometheus中的promQL语句
    Linux——监控GPU集群显存并自动运行python训练脚本
    物联网AI MicroPython传感器学习 之 MQ136硫化氢传感器
    永远在路上
    计算机中的第一个伟大发明(IR/IAR)
  • 原文地址:https://blog.csdn.net/weixin_40422192/article/details/125417456