• 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
  • 相关阅读:
    MySQL学习笔记:索引2
    插件式开发
    Spring 04: IOC控制反转 + DI依赖注入
    远程代码执行漏洞
    性能测试 —— Jmeter 命令行详细
    Kubernetes(1): kubernetes介绍
    解析java中的\r、\n、\r\n、\n\r的区别
    常见磁盘调度算法总结
    docker 搭建rknn转换环境
    GIS原理篇 线性参照
  • 原文地址:https://blog.csdn.net/weixin_40422192/article/details/125417456