Hot100 动态规划

news/2025/2/24 19:12:54

动态规划">动态规划

动规五部曲:

  1. 确定dp数组以及下标的含义
  2. 确定递推公式
  3. dp数组如何初始化
  4. 确定遍历顺序
  5. 举例推导dp数组

70. 爬楼梯 - 力扣(LeetCode)

爬到第一层楼梯有一种方法,爬到二层楼梯有两种方法。

那么第一层楼梯再跨两步就到第三层 ,第二层楼梯再跨一步就到第三层。

所以到第三层楼梯的状态可以由第二层楼梯 和 到第一层楼梯状态推导出来,那么就可以想到动态规划了。

我们来分析一下,动规五部曲:

定义一个一维数组来记录不同楼层的状态

  1. 确定dp数组以及下标的含义

dp[i]: 爬到第i层楼梯,有dp[i]种方法

  1. 确定递推公式

如何可以推出dp[i]呢?

从dp[i]的定义可以看出,dp[i] 可以有两个方向推出来。

首先是dp[i - 1],上i-1层楼梯,有dp[i - 1]种方法,那么再一步跳一个台阶不就是dp[i]了么。

还有就是dp[i - 2],上i-2层楼梯,有dp[i - 2]种方法,那么再一步跳两个台阶不就是dp[i]了么。

那么dp[i]就是 dp[i - 1]与dp[i - 2]之和!

所以dp[i] = dp[i - 1] + dp[i - 2] 。

在推导dp[i]的时候,一定要时刻想着dp[i]的定义,否则容易跑偏。

class Solution {
    public int climbStairs(int n) {
        if(n==1||n==2) return n;
        int[] dp=new int[n+1];
        dp[0]=1;
        dp[1]=1;
        //dp[2]应该是2
        dp[2]=2;
        for(int i=3;i<=n;i++)
        {
            dp[i]=dp[i-1]+dp[i-2];
        }
        return dp[n];
    }
}

746. 使用最小花费爬楼梯 - 力扣(LeetCode)

题目没说明白,脑残的很

class Solution {
    public int minCostClimbingStairs(int[] cost) {
        //这个题他爹的有毛病 cost的长度是n 但是楼梯下标要到n 长度为n+1 
        if(cost.length==2) return Math.min(cost[0],cost[1]);//只有1极楼梯
        int n=cost.length;
         //dp表示到达此处的最小花费
        int[] dp=new int[n+1];
       
        dp[0]=0;
        dp[1]=0;//因为可以选择从0或者1出发
        for(int i=2;i<=n;i++)
        {
            dp[i]=Math.min(dp[i-1]+cost[i-1],dp[i-2]+cost[i-2]);
        }
        return dp[n];
            }
}

 63. 不同路径 II - 力扣(LeetCode)

和62不同路径一样 先初始化横竖两排,然后判断一下有障碍的地方dp就是0

class Solution {
    public int uniquePathsWithObstacles(int[][] obstacleGrid) {
        int m=obstacleGrid.length;
        int n=obstacleGrid[0].length;
        int[][] dp=new int[m][n];
        //如果第一行或第一列中存在障碍物,那么障碍物之后的路径数量应该是0,而不是1。
        for(int i=0;i<obstacleGrid.length;i++)
        {
             if(obstacleGrid[i][0]==0)
            {
                dp[i][0]=1;
            }else{
                break;
            }
        }
        for(int j=0;j<obstacleGrid[0].length;j++)
        {
            if(obstacleGrid[0][j]==0)
            {
                dp[0][j]=1;
            }else{
                break;
            }
        }
        for(int i=1;i<m;i++)
        {
            for(int j=1;j<n;j++)
            {
                if(obstacleGrid[i][j]!=1)
                {
                    dp[i][j]=dp[i-1][j]+dp[i][j-1];
                }else{
                    dp[i][j]=0;
                }
                
            }
        }
        return dp[m-1][n-1];
    }
}

 

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

class Solution {
    public List<List<Integer>> generate(int numRows) {
        List<List<Integer>> res=new ArrayList<>();
        res.add(List.of(1));
        for(int i=1;i<numRows;i++)
        {
            List<Integer> row=new ArrayList<>(i+1);//i+1是元素数量
             //第一个是1
             row.add(1);
              for (int j = 1; j < i; j++) {
                // 左上方的数 + 正上方的数
                row.add(res.get(i - 1).get(j - 1) + res.get(i - 1).get(j));
            }
            //最后一竖是1
            row.add(1);
            res.add(row);
        }
       return res;
    }
}

**343. 整数拆分 - 力扣(LeetCode) 

class Solution {
    public int integerBreak(int n) {
        //dp[i] 为正整数 i 拆分后的结果的最大乘积
        int[] dp = new int[n+1];
        dp[1]=1;
        dp[2]=1;
        for(int i = 3; i <= n; i++) {
            for(int j = 1; j < i;j++) {
               //如果在比较最大值的时候不包括dp[i],那有可能越比越小,倒把一开始找到的最大值给弄丢了
                dp[i] = Math.max(dp[i], Math.max(j*(i-j), j*dp[i-j]));
                // j * (i - j) 是单纯的把整数 i 拆分为两个数 也就是 i,i-j ,再相乘
                //而j * dp[i - j]是将 i 拆分成两个以及两个以上的个数,再相乘。
            }
        }
        return dp[n];
    }
}

 

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

动态规划的的四个解题步骤是:

  • 定义子问题
  • 写出子问题的递推关系
  • 确定 DP 数组的计算顺序
  • 空间优化(可选)
class Solution {
    public int rob(int[] nums) {
        if(nums.length==1) return nums[0];
        if(nums.length==2) return Math.max(nums[0],nums[1]);
        //只有两种状态 偷窃或者不偷窃
        int[] dp=new int[nums.length];
        //表示两种状态中最大获利
       dp[0]=nums[0];
    //    dp[1]=nums[1];不对哦
    dp[1]=Math.max(dp[0],nums[1]);
        //列出状态转移方程
        for(int i=2;i<nums.length;i++)
        {
            dp[i]=Math.max(dp[i-1],dp[i-2]+nums[i]);
        }
        return dp[nums.length-1];
    }
}

首先「完全平方数」有无限个,但要凑成的数字是给定的。

所以首先把所有可能用到的「物品」预处理出来。

从而将问题转换为:给定了若干个数字,每个数字可以被使用无限次,求凑出目标值n所需要用到的是最少数字个数是多少。

152. 乘积最大子数组 - 力扣(LeetCode)

class Solution {
    public int maxProduct(int[] nums) {
     
        int max = Integer.MIN_VALUE, imax = 1, imin = 1;

    for(int i=0; i<nums.length; i++){
            if(nums[i] < 0){ 
//由于存在负数,那么会导致最大的变最小的,最小的变最大的。因此还需要维护当前最小值imin 
//在出现负数这种危机关头计算最大最小
              int tmp = imax;
              imax = imin;
              imin = tmp;
            }
            imax = Math.max(imax*nums[i], nums[i]);//一旦前面有负数就放弃曾经的一切
            imin = Math.min(imin*nums[i], nums[i]);
            
            max = Math.max(max, imax);
        }
        return max;
    }
}


http://www.niftyadmin.cn/n/5864738.html

相关文章

HttpWatch 9.4.17 Pro网页调试与性能优化 资源工具分享

HttpWatch 9.4.17 Pro 是一款专业的网页调试与网络分析工具&#xff0c;专为开发者和网络管理员设计&#xff0c;帮助您轻松监控、分析和优化网页性能。无论是前端开发、后端调试&#xff0c;还是网络性能优化&#xff0c;HttpWatch 都能为您提供强大的支持。 使用方式&#x…

figure机器人技术架构的演进初探——Helix人形机器人控制的革新

一、前言 近期具身智能机器人公司figure提出了人形机器人端到端的控制方案Helix&#xff0c;大小模型结合架构实现了慢速决策规划快速反馈控制的结合&#xff0c;类似于人类的大闹小脑的结构。无疑是人形机器人领域的一项重大突破。作为一个通用的视觉-语言-动作&#xff08;V…

大白话React第三章高级应用阶段

大白话React第三章高级应用阶段 1. 学习 React 路由 在单页应用里&#xff0c;页面不会像传统网页那样每次切换都刷新整个页面&#xff0c;React 路由就像是一个智能的导航员&#xff0c;能让你在一个页面里轻松切换不同的“场景”&#xff0c;就像在一个大房子里从客厅走到卧…

UE5实现角色二段跳

1.二段跳 首先如果不想使用UE中增强输入功能&#xff0c;可以在SetupPlayerInputComponent函数中绑定对应的操作&#xff0c;具体可以自行查找。如果使用增强输入&#xff0c;可以通过创建一个UE自带的第三人称模板C项目学习&#xff0c;假设当前项目是创建自UE第三人称模板项目…

【部署优化篇十三】深度解析《DeepSeek API网关:Kong+Nginx配置指南》——从原理到实战的超详细手册

一、为什么需要API网关?从单体服务到微服务的必然选择 1.1 单体服务的痛点 想象一下早期的淘宝——所有功能(用户中心、商品管理、订单系统)都打包在一个巨型服务里。这样的架构存在三大致命问题: 单点故障:一旦服务崩溃,整个系统瘫痪扩展困难:每次发布都需要全量部署…

git,bash - 从一个远端git库只下载一个文件的方法

文章目录 git,bash - 从一个远端git库只下载一个文件的方法概述笔记写一个bash脚本来自动下载get_github_raw_file_from_url.shreanme_file.shfind_key_value.sh执行命令 END git,bash - 从一个远端git库只下载一个文件的方法 概述 github上有很多大佬上传了电子书库&#xf…

每天一个Flutter开发小项目 (2) : 构建实用的待办事项列表应用

引言 欢迎回到 每天一个Flutter开发小项目 系列博客!在上一篇博客中,我们一起构建了简单的计数器应用,初步体验了 Flutter 的魅力。今天,我们将更进一步,构建一个日常生活中非常实用的应用——待办事项列表。 随着生活节奏的加快,待办事项列表应用成为了我们管理时间和…

基于YOLO11深度学习的运动鞋品牌检测与识别系统【python源码+Pyqt5界面+数据集+训练代码】

《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…