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

动态规划经典例题leetcode思路代码详解

目录

动态规划基础篇例题

leetcode70题.爬楼梯

leetcode746题.使用最小花费爬楼梯

leetcode198题.打家劫舍

leetcode62题.不同路径

leetcode64题.最小路径和

leetcode63题.63不同路径II


动态规划基础篇例题

这一篇的例题解答是严格按照我上一篇写的动态规划三部曲做的,对动态规划不太了解或者比较感兴趣的朋友可以看我上一篇文章。

动态规划算法详解基础篇-CSDN博客

leetcode70题.爬楼梯

70. 爬楼梯 - 力扣(LeetCode)

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

示例 1:

输入:n = 2
输出:2
解释:有两种方法可以爬到楼顶。
1. 1 阶 + 1 阶
2. 2 阶

示例 2:

输入:n = 3
输出:3
解释:有三种方法可以爬到楼顶。
1. 1 阶 + 1 阶 + 1 阶
2. 1 阶 + 2 阶
3. 2 阶 + 1 阶

提示:

  • 1 <= n <= 45
class Solution {/*动态规划三部曲第一步:dp[i]数组含义:表示爬到第i个台阶时,一共有dp[i]种爬法。第二步:求关系时dp[i] dp[i-1] dp[i-2]要么是从i-1跳上来 要么就是从i-2跳上来的 dp[i] = dp[i-1] + dp[i-2];第三步:初始值dp[0] = 1;dp[1] = 1dp[2] = 2;*/public int climbStairs(int n) {if(n <= 1){return 1;}int[] dp = new int[n+1];dp[0] = 1;dp[1] = 1;for(int i = 2; i <= n; i++){dp[i] = dp[i-1] + dp[i-2];}return dp[n];}
}

leetcode746题.使用最小花费爬楼梯

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

给你一个整数数组 cost ,其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶。

你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。

请你计算并返回达到楼梯顶部的最低花费。

示例 1:

输入:cost = [10,15,20]
输出:15
解释:你将从下标为 1 的台阶开始。
- 支付 15 ,向上爬两个台阶,到达楼梯顶部。
总花费为 15 。

示例 2:

输入:cost = [1,100,1,1,1,100,1,1,100,1]
输出:6
解释:你将从下标为 0 的台阶开始。
- 支付 1 ,向上爬两个台阶,到达下标为 2 的台阶。
- 支付 1 ,向上爬两个台阶,到达下标为 4 的台阶。
- 支付 1 ,向上爬两个台阶,到达下标为 6 的台阶。
- 支付 1 ,向上爬一个台阶,到达下标为 7 的台阶。
- 支付 1 ,向上爬两个台阶,到达下标为 9 的台阶。
- 支付 1 ,向上爬一个台阶,到达楼梯顶部。
总花费为 6 。

提示:

  • 2 <= cost.length <= 1000
  • 0 <= cost[i] <= 999
class Solution {/*动态规划三部曲:1、dp[i]:我们爬到第 i 层是,需要花费 dp[i] 元。2、求关系式要跳到 i 层,(1)要么从第 i-1 跳上来 dp[i] = dp[i-1] + cost[i](2)要么从第 i-2 跳上来 dp[i] = dp[i-2] + cost[i]。dp[i] = min(dp[i-1], dp[i-2]) + costfor(i = 2)3、初始值dp[0] = cost[0]dp[1] = cost[1]*/public int minCostClimbingStairs(int[] cost) {int n = cost.length;int[] dp = new int[n];dp[0] = cost[0];dp[1] = cost[1];for(int i = 2; i < n; i++){dp[i] = Math.min(dp[i-1], dp[i-2]) + cost[i];}return Math.min(dp[n-1], dp[n-2]);}
}

leetcode198题.打家劫舍

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

你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。

给定一个代表每个房屋存放金额的非负整数数组,计算你不触动警报装置的情况下,一夜之内能够偷窃到的最高金额。

示例 1:

输入:[1,2,3,1]
输出:4
解释:偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。偷窃到的最高金额 = 1 + 3 = 4 。

示例 2:

输入:[2,7,9,3,1]
输出:12
解释:偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。偷窃到的最高金额 = 2 + 9 + 1 = 12 。

提示:

  • 1 <= nums.length <= 100
  • 0 <= nums[i] <= 400
/*1、dp[i]:到达第i个房间时偷到的最高金额是dp[i]2、dp[i] = nums[i] + dp[i - 2] 偷当前屋子dp[i] = dp[i - 1]  不偷当前屋子选一个比较大的3、dp[0] = nums[0]dp[1] = max(nums[0], nums[1])*/
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] = Math.max(nums[0], nums[1]);// dp[i] = max(nums[i] + dp[i-2], dp[i-1]);for(int i = 2; i < nums.length; i++){dp[i] = Math.max(nums[i] + dp[i-2], dp[i-1]);}return dp[nums.length-1];}
}

leetcode62题.不同路径

62. 不同路径 - 力扣(LeetCode)

一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。

机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。

问总共有多少条不同的路径?

示例 1:

img

输入:m = 3, n = 7
输出:28

示例 2:

输入:m = 3, n = 2
输出:3
解释:
从左上角开始,总共有 3 条路径可以到达右下角。
1. 向右 -> 向下 -> 向下
2. 向下 -> 向下 -> 向右
3. 向下 -> 向右 -> 向下

示例 3:

输入:m = 7, n = 3
输出:28

示例 4:

输入:m = 3, n = 3
输出:6

提示:

  • 1 <= m, n <= 100
  • 题目数据保证答案小于等于 2 * 109
/*1、定义:dp[i][j]:到达[i, j]时,一共有dp[i, j]个路径
2、关系式:dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
3、初始化dp[0][0...m - 1] = 1dp[0...n - 1][0] = 1*/class Solution {public int uniquePaths(int m, int n) {int[][] dp = new int[m][n];// 初始值//最左边的一列for(int i = 0; i < m; i++){dp[i][0] = 1;}//最上边的一行for(int i = 0; i < n; i++){dp[0][i] = 1;}for(int i = 1; i < m; i++){for(int j = 1; j < n; j++){dp[i][j] = dp[i-1][j] + dp[i][j-1];}}return dp[m-1][n-1];}
}

leetcode64题.最小路径和

64. 最小路径和 - 力扣(LeetCode)

给定一个包含非负整数的 *m* x *n* 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。

说明:每次只能向下或者向右移动一步。

示例 1:

img

输入:grid = [[1,3,1],[1,5,1],[4,2,1]]
输出:7
解释:因为路径 1→3→1→1→1 的总和最小。

示例 2:

输入:grid = [[1,2,3],[4,5,6]]
输出:12

提示:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 200
  • 0 <= grid[i][j] <= 200
class Solution {/*动态规划三部曲1、定义数组含义dp[i][j]:当到达 (i,j) 这个位置时,最小路径和为 dp[i][j]。2、关系式dp[i][j]. dp[i-1][j] dp[i][j-1]如何才能到达 (i,j)(1)要么从 (i-1,j) 这个位置向下走一步=>dp[i][j] = dp[i-1][j] + grid[i][j](2)要么是从(i,j-1)这个位置向右走一步=>dp[i][j] = dp[i][j-1] + grid[i][j]dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j]3、初始值dp[0][0~m-1]dp[0~n-1][0]*/public int minPathSum(int[][] grid) {int n = grid.length;int m = grid[0].length;int[][] dp = new int[n][m];// 求初始值dp[0][0] = grid[0][0];for(int j = 1; j < m; j++){dp[0][j] = dp[0][j-1] + grid[0][j];}for(int i = 1; i < n; i++){dp[i][0] = dp[i-1][0] + grid[i][0];}for(int i = 1; i < n; i++){for(int j = 1; j < m; j++){dp[i][j] = Math.min(dp[i-1][j], dp[i][j-1]) + grid[i][j];}}return dp[n-1][m-1];}
}

leetcode63题.63不同路径II

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

一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。

机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish”)。

现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?

网格中的障碍物和空位置分别用 1 和 0 来表示。

示例 1:

img

输入:obstacleGrid = [[0,0,0],[0,1,0],[0,0,0]]
输出:2
解释:3x3 网格的正中间有一个障碍物。
从左上角到右下角一共有 2 条不同的路径:
1. 向右 -> 向右 -> 向下 -> 向下
2. 向下 -> 向下 -> 向右 -> 向右

示例 2:

img

输入:obstacleGrid = [[0,1],[0,0]]
输出:1

提示:

  • m == obstacleGrid.length
  • n == obstacleGrid[i].length
  • 1 <= m, n <= 100
  • obstacleGrid[i][j] 为 0 或 1
class Solution {/*第一步:dp[i][j]:表示走到(i,j)这个地方一共有 dp[i][j]条路径第二步:找关系式if(obstacleGrid[i][j] == 1){dp[i][j] = 0}else{dp[i][j] = dp[i-1][j] + dp[i][j-1]}第三步:初始值dp[0][0] = obstacleGrid[0][0] == 1? 0 : 1; dp[0][j] = dp[0][j-1]dp[i][0] = dp[i-1][0];*/public int uniquePathsWithObstacles(int[][] obstacleGrid) {int n = obstacleGrid.length;int m = obstacleGrid[0].length;int[][] dp = new int[n][m];dp[0][0] = obstacleGrid[0][0] == 1 ? 0 : 1;// 最上面一行for(int j = 1; j < m; j++){dp[0][j] = obstacleGrid[0][j] == 1 ? 0 : dp[0][j-1];}// 最左边一列for(int i = 1; i < n; i++){dp[i][0] = obstacleGrid[i][0] == 1 ? 0 : dp[i-1][0];}for(int i = 1; i < n; i++){for(int j = 1; j < m; j++){if(obstacleGrid[i][j] == 1){dp[i][j] = 0;}else{dp[i][j] = dp[i-1][j] + dp[i][j-1];}}}return dp[n-1][m-1];}
}

相关文章:

  • Oracle-客户端连接报错ORA-12545问题
  • Unity UGUI的自动布局-LayoutGroup(水平布局)组件
  • 深入了解Java中SQL优化的关键技巧与实践
  • 【迅搜03】全文检索、文档、倒排索引与分词
  • ZKP11.4 Use CI to instantiate Fiat-Shamir
  • 麒麟linux离线安装dotnet core
  • 第十九章 解读利用pytorch可视化特征图以及卷积核参数(工具)
  • Jmeter全流程性能测试实战
  • Javascript每天一道算法题(十八)——矩阵置零-中等
  • 2023年微软开源八个人工智能项目
  • linux 开发板以太网通过Ubuntu上外网方法
  • 从书籍结构体中查找定价最高的书籍
  • 一、TIDB基础
  • 个体卫生室电子处方操作流程,私人诊所用什么电子处方系统软件,佳易王诊所电子处方软件配方模板如何设置
  • redis的高可用
  • 【css3】浏览器内核及其兼容性
  • 2018以太坊智能合约编程语言solidity的最佳IDEs
  • JS变量作用域
  • laravel 用artisan创建自己的模板
  • Python 基础起步 (十) 什么叫函数?
  • Python代码面试必读 - Data Structures and Algorithms in Python
  • Sass 快速入门教程
  • SQLServer之创建数据库快照
  • TypeScript实现数据结构(一)栈,队列,链表
  • vue从创建到完整的饿了么(18)购物车详细信息的展示与删除
  • windows-nginx-https-本地配置
  • 仿天猫超市收藏抛物线动画工具库
  • 高程读书笔记 第六章 面向对象程序设计
  • 基于MaxCompute打造轻盈的人人车移动端数据平台
  • ------- 计算机网络基础
  • 使用 Xcode 的 Target 区分开发和生产环境
  • 智能合约Solidity教程-事件和日志(一)
  • postgresql行列转换函数
  • 阿里云ACE认证之理解CDN技术
  • 好程序员web前端教程分享CSS不同元素margin的计算 ...
  • ​​​​​​​​​​​​​​汽车网络信息安全分析方法论
  • ​ArcGIS Pro 如何批量删除字段
  • ​TypeScript都不会用,也敢说会前端?
  • (九)One-Wire总线-DS18B20
  • (欧拉)openEuler系统添加网卡文件配置流程、(欧拉)openEuler系统手动配置ipv6地址流程、(欧拉)openEuler系统网络管理说明
  • (五) 一起学 Unix 环境高级编程 (APUE) 之 进程环境
  • (一)基于IDEA的JAVA基础10
  • (转)mysql使用Navicat 导出和导入数据库
  • ... fatal error LINK1120:1个无法解析的外部命令 的解决办法
  • .net CHARTING图表控件下载地址
  • .net Stream篇(六)
  • @DependsOn:解析 Spring 中的依赖关系之艺术
  • [202209]mysql8.0 双主集群搭建 亲测可用
  • [AIGC 大数据基础]hive浅谈
  • [APIO2012] 派遣 dispatching
  • [C++]AVL树怎么转
  • [C++]二叉搜索树
  • [DM复习]关联规则挖掘(下)
  • [ffmpeg] 定制滤波器
  • [HNOI2008]玩具装箱toy