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

【算法题】63. 不同路径 II-力扣(LeetCode)-”如果起点有障碍物,那么便到不了终点“

【算法题】63. 不同路径 II-力扣(LeetCode)-”如果起点有障碍物,那么便到不了终点“

1.题目

下方是力扣官方题目的地址

63. 不同路径 II

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

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

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

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

示例 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]01

2.题解

这题有两种思路:

思路一:深度优先搜索

思路二:动态规划

思路一

路径问题我们很容易想到的是深度优先来搜索出路径,进而求出结果。

我们将路径想象成树结构,本题要求只能向下或者向右,那么这棵树就是一颗二叉树,如图所示:

在这里插入图片描述

在结合这颗树进行深度优先搜索的时候注意一下边界条件以及路径中的障碍物,这个问题就很容易解决出来了

Python代码

class Solution(object):def uniquePathsWithObstacles(self, obstacleGrid):""":type obstacleGrid: List[List[int]]:rtype: int"""if obstacleGrid[0][0]==1:return 0 # 如果起点有障碍物,那么便到不了终点m=len(obstacleGrid)n=len(obstacleGrid[0])counts=0global countsdef dfs(x,y):global countsif x==m-1 and y==n-1:counts+=1returnfor dx,dy in [[1,0],[0,1]]:if 0<=x+dx<m and 0<=y+dy<n:  # 确保不会越界if obstacleGrid[x+dx][y+dy]!=1:dfs(x+dx,y+dy) # 以及不碰到障碍物dfs(0,0)return counts

不过显然这种方法比较低效,提交时显示的也是显示超时了

在这里插入图片描述

思路二

我们用dp[i,j]来表示从坐标 (0,0) 到坐标 (i,j) 的路径总数

那么dp[i,j]是怎么来的呢?

题目中要求只能向下或者向右走,那么反过来,坐标(i,j)只能由它的上方以及左方走过来,所以

dp[i,j]是dp[i-1,j]和dp[i,j-1]的路径总数的和

这里有一个细节需要注意:

dp元素的初始化值需要是0

这样即使(i,j)的左边或者上边有障碍物,也不影响得出的结果

所以我们可得出状态转移方程:

dp[i][j]=dp[i-1][j]+dp[i][j-1]

当然这题也有以下特殊的边界位置:第一行和第一列

其中起点位置最为特殊且如果起点有障碍物,那么无论无何也到不了终点:

if not obstacleGrid[0][0]:dp[0][0]=1
else:return 0

至于其它第一行的数,它们只能从左边走过来

以及其他第一列的数,它们只能从上边走过来

所以我们可以将它们先走完:

for i in range(1,n):if not obstacleGrid[0][i]:dp[0][i]=dp[0][i-1]
for j in range(1,m):if not obstacleGrid[j][0]:dp[j][0]=dp[j-1][0]

然后我们接着对剩下的位置进行模拟,利用状态转移方程,即可解决该问题

python代码

class Solution(object):def uniquePathsWithObstacles(self, obstacleGrid):""":type obstacleGrid: List[List[int]]:rtype: int"""m=len(obstacleGrid)n=len(obstacleGrid[0])dp=[[0]*n for _ in range(m)]    # 初始化dp数组if not obstacleGrid[0][0]:dp[0][0]=1else:return 0  # 如果起点有障碍物,那么便到不了终点 for i in range(1,n):if not obstacleGrid[0][i]:dp[0][i]=dp[0][i-1]       # 将特殊值模拟完for j in range(1,m):if not obstacleGrid[j][0]:dp[j][0]=dp[j-1][0]for i in range(1,m):for j in range(1,n):                        # 模拟其他正常位置if not obstacleGrid[i][j]:dp[i][j]=dp[i-1][j]+dp[i][j-1]      # 如果这个位置不是障碍物,则利用状态转移方程return dp[-1][-1]

3.结语

该题中,有一个细节:如果起点有障碍物的话,那么路径总数为0

就是本人在注释中所说的:“如果起点有障碍物,那么便到不了终点 ”。

如果不考虑这句话的绝对性,我们在学习算法的过程中何尝不是如此,万事开头难。

我相信,如果我们将学习算法的头给开好,在刚开始而又想放弃的时候再坚持一下,那么我们会在学习算法的道路上越走越远,越走越精通!希望大家在学习算法的过程中不断收获、不断成长!

本人资历尚浅,发博客主要是记录与学习,欢迎大佬们批评指教!大家也可以在评论区多多交流,相互学习,共同成长。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • WebGL颜色与纹理
  • 【制作100个unity游戏之32】unity开发属于自己的一个2d/3d桌面宠物,可以实时计算已经获取的工资
  • QT快速安装使用指南
  • Linux学习/复习2--Linux工具
  • 解决 npm ERR! node-sass 和 gyp ERR! node-gyp 报错问题
  • 蓝桥杯15届C/C++B组省赛题目
  • 【深入学习Redis丨第六篇】Redis哨兵模式与操作详解
  • 【Taro】初识 Taro
  • MyBatis系统学习(四)——MyBatis的关联映射和缓存机制
  • 摆脱困境并在 Android 手机上取回删除照片的所有解决方案
  • 使用vite+react+ts+Ant Design开发后台管理项目(一)
  • Python计算机视觉 第10章-OpenCV
  • vulnhub(12):bob 1.0.1(gpg文件解密)
  • 你了解system V的ipc底层如何设计的吗?消息队列互相通信的原理是什么呢?是否经常将信号量和信号混淆呢?——问题详解
  • 构建高可用和高防御力的云服务架构:从DDoS高防到PolarDB
  • [笔记] php常见简单功能及函数
  • CentOS 7 防火墙操作
  • conda常用的命令
  • Flannel解读
  • JavaScript函数式编程(一)
  • js学习笔记
  • Mysql数据库的条件查询语句
  • Sequelize 中文文档 v4 - Getting started - 入门
  • tweak 支持第三方库
  • 深入浅出webpack学习(1)--核心概念
  • shell使用lftp连接ftp和sftp,并可以指定私钥
  • 扩展资源服务器解决oauth2 性能瓶颈
  • ​​​​​​​STM32通过SPI硬件读写W25Q64
  • ​Java并发新构件之Exchanger
  • ​补​充​经​纬​恒​润​一​面​
  • ​第20课 在Android Native开发中加入新的C++类
  • #HarmonyOS:软件安装window和mac预览Hello World
  • ( 用例图)定义了系统的功能需求,它是从系统的外部看系统功能,并不描述系统内部对功能的具体实现
  • (003)SlickEdit Unity的补全
  • (C语言版)链表(三)——实现双向链表创建、删除、插入、释放内存等简单操作...
  • (二) Windows 下 Sublime Text 3 安装离线插件 Anaconda
  • (六) ES6 新特性 —— 迭代器(iterator)
  • (每日一问)操作系统:常见的 Linux 指令详解
  • (转)EXC_BREAKPOINT僵尸错误
  • (转)编辑寄语:因为爱心,所以美丽
  • (转载)(官方)UE4--图像编程----着色器开发
  • (转载)PyTorch代码规范最佳实践和样式指南
  • ./和../以及/和~之间的区别
  • .naturalWidth 和naturalHeight属性,
  • .NET Core IdentityServer4实战-开篇介绍与规划
  • .NET Core WebAPI中使用Log4net 日志级别分类并记录到数据库
  • .NET 使用配置文件
  • 。。。。。
  • @Autowired标签与 @Resource标签 的区别
  • @Transactional 竟也能解决分布式事务?
  • [ HTML + CSS + Javascript ] 复盘尝试制作 2048 小游戏时遇到的问题
  • [ vulhub漏洞复现篇 ] ECShop 2.x / 3.x SQL注入/远程执行代码漏洞 xianzhi-2017-02-82239600
  • [2018-01-08] Python强化周的第一天
  • [240621] Anthropic 发布了 Claude 3.5 Sonnet AI 助手 | Socket.IO 拒绝服务漏洞
  • [AI]ChatGPT4 与 ChatGPT3.5 区别有多大