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

ops/2024/9/22 18:28:01/

算法题】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

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

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

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

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


http://www.ppmy.cn/ops/114366.html

相关文章

nginx 文件尺寸过大解决方案

http { # 其他配置... client_max_body_size 1M; # 这是默认值&#xff0c;也可以在 server 块中覆盖 # 其他配置... } server { listen 80; server_name shop.yanmishu.cn; # 如果有这个配置&#xff0c;则会覆盖 http 块中的设置 …

剪映草稿批量自动化导出教程实操演示

如何批量自动导出草稿&#xff1f;今天我来实操演示。首先打开谷歌剪映助手 如果没有安装谷哥剪映助手的可以自行搜索下载&#xff0c;打开后找到批量导出多个草稿自动化导出。接着在右侧输入你要导出草稿的数量&#xff0c;其他的选项根据需求自行选择&#xff0c;最后点击立即…

C++类和对象(4)

1. 再探构造函数 之前我们实现构造函数时&#xff0c;初始化成员变量主要在构造函数体内赋值&#xff0c;构造函数初始化还有⼀种方 式&#xff0c;就是初始化列表&#xff0c;初始化列表的使用方式是以⼀个冒号开始&#xff0c;接着是⼀个以逗号分隔的数据成 员列表&#xf…

ChatGPT 4o 使用指南 (9月更新)

首先基础知识还是要介绍得~ 一、模型知识&#xff1a; GPT-4o&#xff1a;最新的版本模型&#xff0c;支持视觉等多模态&#xff0c;OpenAI 文档中已经更新了 GPT-4o 的介绍&#xff1a;128k 上下文&#xff0c;训练截止 2023 年 10 月&#xff08;作为对比&#xff0c;GPT-4…

FGT-KVM虚拟机安装步骤

根据FortiOS release note要求&#xff0c;KVM要求的安装条件CentOS 6.4 (qemu 0.12.1) or later。 1.安装CentOS 6.5 CentOS-6.5-x86_64-LiveDVD.iso 下载种子: 2.是否支持虚拟机 egrep ‘(vmx|svm)’ --coloralways /proc/cpuinfo [rootlocalhost ~]# egrep ‘(vmx|svm)’…

Web后端开发技术:RESTful 架构详解

RESTful 是一种基于 REST&#xff08;表述性状态转移&#xff0c;Representational State Transfer&#xff09;架构风格的 API 设计方式&#xff0c;通常用于构建分布式系统&#xff0c;特别是在 Web 应用开发中广泛应用。REST 是一种轻量级的架构模式&#xff0c;利用标准的 …

动态规划part07

LC 198.打家劫舍 关键&#xff1a;dp[i]的含义是考虑下标i及之前&#xff0c;能偷的最多的钱是多少&#xff0c;那么对于下标i 有 两种情况&#xff0c;偷或不偷 &#xff0c; 这又依赖于前一个房间&#xff0c;和前前个房间是否被偷。若偷 i &#xff0c; 那么dp[i] dp[i-2]…

【rust】rust条件编译

在c语言中&#xff0c;条件编译是一个非常好用的功能&#xff0c;那么rust中如何实现条件编译呢? rust的条件编译需要两个部分&#xff0c;一个是fratures&#xff0c;另一个是cfg。Cargo feature是一个非常强大的功能&#xff0c;可以提供条件编译和可选依赖项的高级特性&…