力扣:63. 不同路径 II(动态规划)

题目:

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

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

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

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

示例 1:
在这里插入图片描述

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

  1. 向右 -> 向右 -> 向下 -> 向下
  2. 向下 -> 向下 -> 向右 -> 向右

示例 2:

在这里插入图片描述

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

提示:

m == obstacleGrid.length
n == obstacleGrid[i].length
1 <= m, n <= 100
obstacleGrid[i][j] 为 0 或 1

思路:

这道题相对于力扣:62. 不同路径(动态规划,附python二维数组的定义)就是有了障碍。
不同路径中我们已经详细分析了没有障碍的情况,有障碍的话,其实就是标记对应的dp数组保持初始值0就可以了。

动规五部曲:

  1. 确定dp数组以及下标的含义(跟上题一样)

这里要明确dp数组的含义,定义dp数组是为了找到不同路径,
dp[i][j] :表示从(0 ,0)出发,到(i, j) 有dp[i][j]条不同的路径。

  1. 确定递推公式

递归公式跟上题一样,dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
但这里需要注意一点,因为有了障碍,(i, j)如果就是障碍的话应该就保持初始状态(初始状态为0)。

代码如下:

                if obstacleGrid[i][j] == 0:dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
  1. dp数组如何初始化

这里的初始化是重点,
如果(i, 0) 这条边有了障碍之后,障碍之后(包括障碍)都是走不到的位置了,所以障碍之后的dp[i][0]应该还是初始值0。下标(0, j)的初始化情况同理。

所以本题初始化代码为:

        for i in range(n):if obstacleGrid[0][i] == 0:dp[0][i] = 1else:breakfor j in range(m):if obstacleGrid[j][0] == 0:dp[j][0] = 1else:break

注意:一旦遇到obstacleGrid[i][0] == 1的情况,一定要退出循环!不然之后障碍之后的点依旧会被赋值。

  1. 确定遍历顺序(跟上题一样)

从递归公式dp[i][j] = dp[i - 1][j] + dp[i][j - 1] 中可以看出,一定是从左到右一层一层遍历,这样保证推导dp[i][j]的时候,dp[i - 1][j] 和 dp[i][j - 1]一定是有数值。

  1. 举例推导dp数组

拿示例1来举例如题:

在这里插入图片描述
对应的dp数组如图:
在这里插入图片描述

完整代码:

class Solution:def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int:# 获取网格的列数和行数n = len(obstacleGrid[0])m = len(obstacleGrid)# 如果起点或终点有障碍物,直接返回0if obstacleGrid[0][0] == 1 or obstacleGrid[m - 1][n - 1] == 1:return 0# 初始化一个二维数组dp,用于存储到达每个位置的路径数量dp = [[0] * n for _ in range(m)]# 初始化第一行,如果没有障碍物,则到达每个位置的路径数量为1,否则后面的位置均不可达for i in range(n):if obstacleGrid[0][i] == 0:dp[0][i] = 1else:break# 初始化第一列,如果没有障碍物,则到达每个位置的路径数量为1,否则后面的位置均不可达for j in range(m):if obstacleGrid[j][0] == 0:dp[j][0] = 1else:break# 计算其余位置的路径数量for i in range(1, m):for j in range(1, n):# 如果当前位置没有障碍物,则到达当前位置的路径数量为到达上方和左方位置的路径数量之和if obstacleGrid[i][j] == 0:dp[i][j] = dp[i - 1][j] + dp[i][j - 1]# 返回到达终点的路径数量return dp[m - 1][n - 1]

复杂度分析:

  • 时间复杂度:O(n × m),n、m 分别为obstacleGrid 长度和宽度
  • 空间复杂度:O(n × m)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/586637.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

推荐的 Web 性能计时:多长时间才算太长?

对于加载页面时的缓慢速度没有明确的规定&#xff0c;但有具体的指导原则来指示内容将加载&#xff08;1 秒&#xff09;、空闲&#xff08;50 毫秒&#xff09;、动画&#xff08;16.7 毫秒&#xff09;和响应用户输入&#xff08;50 到 50 毫秒&#xff09;。 200 毫秒&#…

SVN下载安装(服务器与客户端)

1.下载 服务器下载&#xff1a;Download | VisualSVN Server 客户端下载&#xff1a;自行查找 2. 服务器安装 双击执行 运行 下一步 同意下一步 下一步 选中安装目录 3. 客户端安装 双击执行 下一步 4. 服务器创建仓库 5. 服务器创建用户 6. 客户端获取资源 文件夹右键

用idea跑起十多年前的项目

一、eclipse的项目 先删掉一些eclipse的配置文件 二、在idea中导入项目 1、导入成功后&#xff0c;先【锤一下】 2、然后发现编译不通过&#xff0c;非常多的报错信息&#xff0c;逐一解决报错 &#xff08;1&#xff09;tomcat7配置报错 &#xff08;2&#xff09;先删除tom…

java springboot将接口查询数据放在系统中 一小时系统更新一次 避免用户访问接口查询数据库缓慢

真到了公司 很多数据库表 特别是常用的功能业务对应的 都是几百万条起步的数据 查询会比较缓慢 那么 我们就可以不用每次都真的查询数据库 例如 我这里有一个接口 通过 封装的 IBookService.list 函数去查询数据库 接口返回是这样的 我们先在启动类 条件装配上 这个接口所在的…

vivado CDC约束-“设置总线倾斜”对话框

“设置总线倾斜”对话框 在AMD Vivado™ IDE中&#xff0c;可以通过多种方式设置总线偏斜约束&#xff1a; •通过时间约束编辑器。选择窗口 → 时间限制 → 断言 → 设置总线倾斜。从“时序约束编辑器”中&#xff0c;可以添加、删除或修改总线扭曲约束。 注意&#…

【C++】循环结构中的变量的生命周期

在C中&#xff0c;循环结构中变量的生命周期取决于变量的作用域和声明位置。 for(int i 0; i < 5; i) //i为循环变量&#xff0c;在循环结构刚开始时被创建&#xff0c;在整个循环结构结束时被销毁 {int x i; // x为循环体中的变量&#xff0c;在每次开始循环体时会被创…

day11--java高级编程:反射

4 Day18–反射 本章专题与脉络 1. 反射(Reflection)的概念 1.1 反射的出现背景 Java程序中&#xff0c;所有的对象都有两种类型&#xff1a;编译时类型和运行时类型&#xff0c;而很多时候对象的编译时类型和运行时类型不一致&#xff08;多态&#xff09;。 Object obj n…

【AIGC科技展望】预测AIGC2025年的机会与挑战

2025年&#xff0c;AIGC的机会与挑战 在未来的五年里&#xff0c;AIGC&#xff08;AI Generated Content&#xff09;将会成为一个越来越重要的领域。但是&#xff0c;伴随着机会而来的是挑战。在这篇文章中&#xff0c;我们将一起探讨AIGC的机会与挑战&#xff0c;并预测2025…

uniapp获取用户头像

在uniapp中&#xff0c;你可以使用uni.getUserInfo方法来获取用户的头像信息&#xff0c;具体步骤如下&#xff1a; 在需要获取用户头像的页面中&#xff0c;引入uni-app的API&#xff1a;import uni from dcloudio/uni-app; 在需要的地方调用uni.getUserInfo方法来获取用户的…

机器学习系列13:通过随机森林获取特征重要性

我们已经知道通过 L1 正则化和 SBS 算法可以用来做特征选择。 我们还可以通过随机森林从数据集中选择相关的特征。随机森林里面包含了多棵决策树&#xff0c;我们可以通过计算特征在每棵决策树决策过程中所产生的的信息增益平均值来衡量该特征的重要性。 你可能需要参考&…

使用官网Spring Initializr创建一个满足您需求的Spring Boot项目,包括建议目录配置

为了创建一个满足您需求的Spring Boot项目&#xff0c;我们将在https://start.spring.io/Spring Initializr中选择合适的依赖。以下是基于您的描述所推荐的依赖项&#xff1a; Spring Web&#xff1a;用于开发RESTful API。Spring Data JPA&#xff08;但排除Spring Boot默认数…

Mybatis-Plus使用小记

MP 使用小记 所谓 MP 是指&#xff1a;Mybatis-Plus 前言 本篇文章是对 MP 一些日常开发学习中不常见但实用的使用小技巧总结&#xff0c;内容将持续更新&#xff0c;希望能对小伙伴们有所帮助。推荐点赞 收藏哦&#xff01; 官方文档&#xff1a;Mybatis-Plus 给现有分页指…

Activemq性能优化

生产者流量限制 ActiveMQ支持为每个生产者单独设置流量控制。流量控制的含义&#xff1a;当生产者产生消息过快&#xff0c;超过流量限制的时候&#xff0c;生产者将会被阻塞直到资源可以继续使用&#xff0c;或者抛出一个JMSException。 同步发送消息&#xff08;useAsynSen…

力扣:509. 斐波那契数(动态规划,附带递归版本) 详细讲解动态规划的思路

题目&#xff1a; 斐波那契数 &#xff08;通常用 F(n) 表示&#xff09;形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始&#xff0c;后面的每一项数字都是前面两项数字的和。也就是&#xff1a; F(0) 0&#xff0c;F(1) 1 F(n) F(n - 1) F(n - 2)&#xff0c;其中…

速盾cdn:cdn加速原理是什么

CDN&#xff08;内容分发网络&#xff09;通过在全球各地部署服务器节点来加速内容传输&#xff0c;提高用户访问网站时的响应速度和性能。速盾CDN作为一种CDN服务提供商&#xff0c;其加速原理主要涉及以下几个关键步骤&#xff1a; 内容缓存&#xff1a; 当用户访问一个网站时…

【Spring实战】12 Thymeleaf

文章目录 1. 定义2. 设计目标3. 官网4. Spring 集成 Thymeleaf1&#xff09;添加依赖2&#xff09;创建模版3&#xff09;创建Controller4&#xff09;启动程序5&#xff09;执行验证 5. 代码详细总结 1. 定义 Thymeleaf 是一个用于在 Web 应用程序中进行服务器端 Java 模板渲…

Git:远程仓库的使用

查看当前的远程库 要查看当前配置有哪些远程仓库&#xff0c;可以用git remote 命令&#xff0c;它会列出每个远程库的简短名字。在克隆完某个项目后&#xff0c;至少可以看到一个名为origin 的远程库&#xff0c;Git 默认使用这个名字来标识你所克隆的原始仓库&#xff1a; 也…

UE4运用C++和框架开发坦克大战教程笔记(十三)(第40~42集)

UE4运用C和框架开发坦克大战教程笔记&#xff08;十三&#xff09;&#xff08;第40~42集&#xff09; 40. 多按键绑定41. 自动生成对象42. 资源模块数据结构测试自动生成对象按资源类型生成对象 40. 多按键绑定 上节课实现了按键绑定系统的 4 种基础绑定&#xff0c;这节课来…

自动化部署与容器化:构建现代化DevOps工作流

流畅DevOps之路&#xff1a;探秘自动化部署和容器化的前沿技术 前言 随着软件开发的复杂性不断增加&#xff0c;传统的手动部署和管理方式已无法满足迅速变化的需求。本文将探讨现代DevOps实践中的关键技术&#xff0c;从容器化到自动化部署&#xff0c;以及涉及到的关键工具…

python+django高校教材共享管理系统PyCharm 项目

本中原工学院教材共享平台采用的数据库是mysql&#xff0c;使用nodejs技术开发。在设计过程中&#xff0c;充分保证了系统代码的良好可读性、实用性、易扩展性、通用性、便于后期维护、操作方便以及页面简洁等特点。系统所要实现的功能分析&#xff0c;对于现在网络方便的管理&…