当前位置: 首页 > article >正文

力扣100题——动态规划

爬楼梯

题目

70. 爬楼梯 - 力扣(LeetCode)

思路

动态规划关键在于写出状态转移方程,根据题目的意思每次能上一个台阶或两个台阶

  • 用dp数组,dp[i]代表上到第i个台阶最多有几种的方法
  • 那么很容易就可以推出 dp[i]=dp[i-1]+dp[i-2]
  • 对dp数组进行初始化,根据推理,很容易可以得到dp[0]=0,dp[1]=1,dp[2]=2;
  • 最后根据状态转移方程开始推dp的所有值

代码

public int climbStairs(int n) {
        int[] dp = new int[n+1];
        if(n==0){
            return 0;
        }
        if(n<2){
            return 1;
        }
        dp[0] = 0;
        dp[1] = 1;
        dp[2] = 2;
        for(int i=3;i<=n;i++){
            dp[i] = dp[i-1]+dp[i-2];
        }
        return dp[n];
    }

杨辉三角

题目

118. 杨辉三角 - 力扣(LeetCode)

思路

根据题目给出的状态转移方程直接模拟实现,优化思路在于

  • 去除二维数组:我们不需要预先声明一个二维数组,只需动态地生成每一行,并将结果存入最终的 List<List<Integer>>
  • 直接填充每行元素:根据帕斯卡三角形的性质,第 i 行的第 j 个元素为上一行的第 j-1 个元素和第 j 个元素之和。我们只需按这个规则生成每一行即可。
  • 减少不必要的检查:当前代码中的一些边界条件检查和赋值可以通过初始化每行的第一个和最后一个元素为 1 来避免。

代码

直接模拟

public List<List<Integer>> generate(int numRows) {
        List<List<Integer>> res = new ArrayList<>();
        if(numRows==0){
            return res;
        }
        int[][] result = new int[numRows][numRows];
        for(int i=0;i<numRows;i++){
            result[numRows-1][i]=1;
            result[i][0]=1;
        }
        for(int i=0;i<numRows;i++){
            for(int j=0;j<numRows;j++){
                if(i==j){
                    result[i][j]=1;
                }
            }
        }
        for(int i=0;i<numRows;i++) {
            for (int j = 0; j < numRows; j++) {
                if((i-1)>=0&&(j-1)>=0&&result[i][j-1]>0&&result[i-1][j-1]>0){
                    result[i][j] = result[i-1][j-1]+result[i-1][j];
                }
            }
        }
        for(int i=0;i<numRows;i++) {
            List<Integer> list = new ArrayList<>();
            for (int j = 0; j < numRows; j++) {
                if(result[i][j]>0){
                    list.add(result[i][j]);
                }
            }
            res.add(list);
        }
        return res;
    }

优化

public List<List<Integer>> generate(int numRows) {
        List<List<Integer>> res = new ArrayList<>();
        for(int i=0;i<numRows;i++){
            List<Integer> row = new ArrayList<>();
            for(int j=0;j<i+1;j++){
                if(j==0||j==i){
                    row.add(1);
                }else{
                    row.add(res.get(i-1).get(j-1)+res.get(i-1).get(j));
                }
            }
            res.add(row);
        }
        return res;
    }

打家劫舍

题目

198. 打家劫舍 - 力扣(LeetCode)

思路

根据题目找出状态转移方程,使用dp数组保存记录,dp[i]即为当前偷的最大值

因为不能偷相邻的房子,所以dp[i] = max( dp[i-1] ,dp[i-2]+nums[i])

代码

public int rob(int[] nums) {
        int n = nums.length;
        if(nums.length==0){
            return 0;
        }
        if(nums.length==1){
            return nums[0];
        }
        int[] dp = new int[n];
        dp[0] = nums[0];
        dp[1] = Math.max(nums[0], nums[1]);
        for(int i=2;i<n;i++){
            dp[i] = Math.max(dp[i-1], dp[i-2]+nums[i]);
        }
        return dp[n-1];
    }

完全平方数

题目

279. 完全平方数 - 力扣(LeetCode)

思路

  • 定义状态dp[i] 表示和为 i 的最少完全平方数数量。
  • 状态转移方程
    • 对于每个 i,我们尝试从较小的完全平方数开始,假设平方数为 j * j,则 dp[i] = min(dp[i], dp[i - j * j] + 1)
    • dp[i - j * j] 表示剩余的部分 i - j * j 的最少数量,再加上一个平方数 j * j
  • 初始条件dp[0] = 0,因为和为 0 不需要任何平方数。

代码

public int numSquares(int n) {
        int[] dp = new int[n+1];
        Arrays.fill(dp, Integer.MAX_VALUE);
        dp[0] = 0;
        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];
    }

零钱兑换

题目

322. 零钱兑换 - 力扣(LeetCode)

思路

  • 和上一题类似,找出状态转移方程,dp[i] 表示总额为 i 的最少硬币数量。
  • dp[i] = Math.min(dp[i], dp[i - coin] + 1);

代码

public int coinChange(int[] coins, int amount) {
        int[] dp = new int[amount+1];
        Arrays.fill(dp, Integer.MAX_VALUE);
        dp[0] = 0;
        for(int i=1;i<=amount;i++){
            for (int coin : coins) {
                if (i >= coin && dp[i - coin] != Integer.MAX_VALUE) {
                    dp[i] = Math.min(dp[i], dp[i - coin] + 1);
                }
            }
        }
        return dp[amount] == Integer.MAX_VALUE ? -1 : dp[amount];
    }


http://www.kler.cn/a/301283.html

相关文章:

  • 在MATLAB中导入TXT文件的若干方法
  • web——upload-labs——第十二关——%00截断
  • IntelliJ IDEA 2024.3(Ultimate Edition)免费化教学
  • 图像重建之深度学习重建
  • 【时间之外】IT人求职和创业应知【37】-AIGC私有化
  • linux之调度管理(5)-实时调度器
  • 【MATLAB】数据和字符串类型转换
  • 路由器出现DNS(Domain Name System)没有被解析的情况,没有被解析的情况,通常是由多种原因导致的。以下是一些可能的原因及相应的解释:
  • TDSQL:腾讯分布式数据库系统的核心要点与优势分析
  • Java之枚举
  • macos 系统文件操作时提示 Operation not permitted 异常解决方法 , 通过恢复模式 开启 /关闭 SIP方法
  • debian12实践-安装docker
  • 日志框架log4j打印异常堆栈信息携带traceId,方便接口异常排查
  • Redisson实现订单到期关闭
  • 论文阅读_检索增强生成 RAG 综述
  • 架构模式:MVC
  • harbor目录结构和镜像存储机制是什么
  • (详细文档)javaswing学生成绩管理系统(mysql)+详细报告
  • 汤臣倍健,三七互娱,得物,顺丰,快手,游卡,oppo,康冠科技,途游游戏,埃科光电25秋招内推
  • 【预训练语言模型】BERT原理解析、常见问题
  • java8:obsclient下载文件,restful风格
  • springboot 项目获取 yaml/yml (或 properties)配置文件信息
  • jenkins工具的介绍和gitlab安装
  • c# 视觉识别图片文字 二维码
  • 贪心问题———区间覆盖
  • web基础之信息泄露