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

server/2024/9/22 16:51:08/

算法题】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/server/120360.html

相关文章

Elasticsearch 检索优化:停用词的应用

Elasticsearch 检索优化&#xff1a;停用词的应用 场景描述 目前在 Elasticsearch 集群中存储约 1.5 亿篇文章数据&#xff0c;随着数据量的增加&#xff0c;检索性能问题逐渐显现。在列表检索和聚合操作中&#xff0c;CPU 消耗飙升至 100%&#xff0c;并且检索耗时较长&…

SSM+vue音乐播放器管理系统

音乐播放器管理系统 随着社会的发展&#xff0c;计算机的优势和普及使得音乐播放器管理系统的开发成为必需。音乐播放器管理系统主要是借助计算机&#xff0c;通过对首页、音乐推荐、付费音乐、论坛信息、个人中心、后台管理等信息进行管理。减少管理员的工作&#xff0c;同时…

LangChain教程 - 支持的向量数据库列举

系列文章索引 LangChain教程 - 系列文章 向量数据库是现代自然语言处理应用中不可或缺的组件&#xff0c;它们可以高效地存储、索引和检索嵌入向量&#xff0c;支持大规模的相似性搜索任务。LangChain 是一个强大的框架&#xff0c;允许开发者轻松将大型语言模型与向量数据库结…

【吊打面试官系列-MySQL面试题】MyISAM 表格将在哪里存储,并且还提供其存储格式?

大家好&#xff0c;我是锋哥。今天分享关于【MyISAM 表格将在哪里存储&#xff0c;并且还提供其存储格式&#xff1f;】面试题&#xff0c;希望对大家有帮助&#xff1b; MyISAM 表格将在哪里存储&#xff0c;并且还提供其存储格式&#xff1f; 每个 MyISAM 表格以三种格式存储…

Broadcast:Android中实现组件及进程间通信

目录 一&#xff0c;Broadcast和BroadcastReceiver 1&#xff0c;简介 2&#xff0c;广播使用 二&#xff0c;静态注册和动态注册 三&#xff0c;无序广播和有序广播 1&#xff0c;有序广播的使用 2&#xff0c;有序广播的截断 3&#xff0c;有序广播的信息传递 四&am…

【Git】分支管理

本篇博客的环境为 Ubuntu/linux 文章目录 前言分支基础操作创建分支切换分支合并分支删除分支 合并冲突分支管理策略分支策略bug 分支 前言 在 Git 中&#xff0c;分支(branch)是一个独立的开发线路。允许在不影响主线(通常是main或master分支)的情况下进行修改和开发 主线就是…

【VUE】快速上手

一、快速上手 创建HTML文件引入vue.js <script src"https://unpkg.com/vue3/dist/vue.global.js"></script> <script src"https://cdn.bootcdn.net/ajax/libs/vue/3.3.4/vue.global.prod.js"></script>按照vue.js的语法编写代码…

专业学习|动态规划(概念、模型特征、解题步骤及例题)

一、引言 &#xff08;一&#xff09;从斐波那契数列引入自底向上算法 &#xff08;1&#xff09;知识讲解 &#xff08;2&#xff09;matlap实现递归 &#xff08;3&#xff09;带有备忘录的遗传算法 &#xff08;4&#xff09;matlap实现带有备忘录的递归算法 “&#xff1…