• 动态规划专题:LeetCode 完全平方数


    原题链接

    279. 完全平方数

    思路

    这道题跟之前的动态规划有些区别。刷了不少动态规划的题目。大部分的结构,都是类似于这种形式

    dp[i] = Math.max(min)(dp[i-n]+k, dp[i-m]+k1) + M
    

    这种形式,涉及到最大小值,肯定涉及到题目求解的最值问题

    而且一般绝大多数情况下是,时间复杂度都是O(n)。

    这次的题目,主要涉及到一些关键点的处理。

    如果不考虑这些关键点,无非就是

    dp[i] 表示数字为i的时候,最少的平方数字组成,也就问题所要的答案
    dp[i] = dp[i-1] + 1(数字i-1加上1,就可以得到i)
    

    关键点

    不考虑平方数的时候,比如当 n = 4 的时候,dp[4] = dp[3]+1

    但是如果考虑平方数的话,dp[4] = 2^2

    然后就一直纠结关键点怎么处理。看了题解,用了遍历。

    遍历

    for(int i = 1; i <= n; i++){
        dp[i] = n; // 等价 dp[i] = dp[i-1]+1;
        for(int j = 1; i-j*j>=0; j++){
            dp[i] = Math.min(dp[i], dp[i-j*j]+1);
        }
    }
    

    因为无法判断哪个数的平方可以满足条件。所以需要去遍历。比如对于 n = 4,需要去遍历,4 - 1, 4 - 2^2。需要去取这些遍历的最小值。

    注意:因为需要去取这些情况的最值,所以 min 必须含有其本身,所以这种结构,需要一开始去给dp[i]设置一个大的值,dp[i] = n只是这里的特殊情况,其实 dp[i] = dp[i-1]+1 。是不考虑平方数所需最少的数,也就是dp[i]的上界。

    如果还不是很清楚,举个例子

    dp[4] = min(dp[3]+1, dp[4-1]+1, dp[4-2^2]+1)
    dp[10] = min(dp[9]+1, dp[10-1]+1, dp[10-2^2]+1, dp[10-3^3]+1)
    拆解为——————>
    dp[4] = min(dp[3]+1, dp[4-1]+1)
    dp[4] = min(dp[4], dp[4-2^2]+1)
    ----------->
    

    只不过这个min中所含的参数个数是一直变化的,所以需要遍历。

    其次,因为遍历,所以一定要与之前求的值进行比较。所以需要在遍历前进行初始化。

    实现

    class Solution {
        public int numSquares(int n) {
            int[] dp = new int[n+1];
            for(int i = 1; i <= n; i++){
                dp[i] = dp[i-1]+1;
                for(int j = 1; i-j*j>=0; j++){
                    dp[i] = Math.min(dp[i], dp[i-j*j]+1);
                }
            }
            return dp[n];
    
        }
    }
    
  • 相关阅读:
    Java使用AES算法
    Python中使用AES算法(解决Python2.x和3.x下运行不兼容问题)
    关于递归
    zabbix文档3.4
    CentOS-7.3.1611编译安装 Nginx-1.12.1+mysql-5.7.19+PHP-7.1.8+zabbix-3.4.1
    搭建zabbix服务器监控
    php编译安装过程中遇到问题
    springboot 获取控制器参数的几种方式
    spring boot 全局异常处理及自定义异常类
    Java 中的异常和处理详解
  • 原文地址:https://www.cnblogs.com/zhouzhiyao/p/12563030.html
Copyright © 2020-2023  润新知