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

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

时间:2024-09-25 23:19:33浏览次数:8  
标签:II obstacleGrid 障碍物 路径 力扣 range 63 起点 dp

【算法题】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=0
        global counts
        def dfs(x,y):
            global counts
            if x==m-1 and y==n-1:
                counts+=1
                return
            for 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]=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]
        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

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

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

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

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

标签:II,obstacleGrid,障碍物,路径,力扣,range,63,起点,dp
From: https://blog.csdn.net/Janium/article/details/142427032

相关文章

  • SSM项目实战II基于SSM的培训机构运营系统(开发文档+数据库+源码)
    目录一、前言二、技术介绍三、系统实现四、论文参考五、核心代码六、源码获取全栈码农以及毕业设计实战开发,CSDN平台Java领域新星创作者一、前言随着知识经济的兴起,教育培训行业迎来了前所未有的发展机遇。传统培训机构在追求教学质量的同时,也面临着运营管理效率提......
  • The 2024 ICPC Asia East Continent Online Contest (II)
    C.PrefixofSuffixes比赛的时候调E,调的心态爆炸,最后一点时间写C,又没冲出来题目大意给三个数组\(\{S_n\},\{a_n\},\{b_n\}\),对于每个\(i\)求\(\sum_{j=1}^i\sum_{k=j}^{j+z_j-1}A_kB_j\),其中\(z_i\)表示\(S_{[1,i]}\)和\(S_{[j,i]}\)的最长公共前缀的长度,\(S\)数组强制在线\[......
  • IIS Web服务器安装配置教程(图文)---IIS安装(win10)
    IIS是一种Web(网页)服务组件,其中包括Web服务器、FTP服务器、NNTP服务器和SMTP服务器,分别用于网页浏览、文件传输、新闻服务和邮件发送等方面,它使得在网络(包括互联网和局域网)上发布信息成了一件很容易的事。IIS是什么很多朋友都不知道IIS是什么?其实IIS是InternetInformation......
  • IIS部署前端代码和后端api
    环境准备:安装net8运行时 https://dotnet.microsoft.com/zh-cn/download/dotnet/8.0 第一步:安装IIS 第二步:安装完成后,打开IIS管理器 第三步:部署后端api服务1.选择网站右键"添加网站"  2,点击确定添加3.添加完成后,选中刚刚添加的网站,点击预览网站4:如......
  • COMP 636: Web App Mnagement simulator (FMS)
    COMP636:WebAppAssessment–S22024Milestonesubmissiondue:5pmFriday4October2024viaLearnFinalsubmissiondue:5pmTuesday29October2024viaLearnWorth:50%ofCOMP636gradeSubmitviaAkoraka|Learn,withfilessetupandavailableonG......
  • STM32驱动1.3寸(0.96寸)OLED显示屏 #基于HAL库#软件IIC通讯
    前言  本文用作记录基于HAL库搭建起来的软件IIC驱动OLED显示器。一、软件IIC原理  只需理解两点:1.IIC是一种通信总线,物理层面用于单片机与OLED的通信。2.软件IIC即模拟硬件IIC的引脚时序,可以灵活配置引脚。IC物理接口:IIC串行总线有两根信号线,一根是双向的数据线SDA,另......
  • 【Linux】多线程:线程池的创建、日志类、RAII互斥锁、单例模式:饿汉方式与懒汉方式
    目录一、线程池概念二、线程的封装及线程池类成员变量的介绍 三、单例模式饿汉方式(EagerInitialization)懒汉方式(LazyInitialization)四、RAII类型的互斥锁 五、日志类的实现六、简单的任务类创建七、线程池的创建 一、线程池概念线程池(ThreadPool)是一种基于......
  • 【LTSpice】【LTM4630】【2. 电压调节仿真】
    文章目录前言一、搭建电路二、开始仿真三.读取直流电压总结前言本篇学习使用LTSpice仿真观察LTM4630的电路,通过阅读手册,自己搭建电路,并配置参数,观察电压输出的变化。一、搭建电路打开LTSpice软件后,Ctrl+N新建一个图纸。按快捷键P,进入器件选择界面,输入LTM4630,单击......
  • 【算法题】20. 有效的括号-力扣(LeetCode)
    【算法题】20.有效的括号-力扣(LeetCode)1.题目下方是力扣官方题目的地址20.有效的括号给定一个只包括'(',')','{','}','[',']'的字符串s,判断字符串是否有效。有效字符串需满足:左括号必须用相同类型的右括号闭合。左括号必须以正确的顺序闭合。每个右括号都有一个对......
  • 【算法题】11. 盛最多水的容器-力扣(LeetCode)
    【算法题】11.盛最多水的容器-力扣(LeetCode)1.题目下方是力扣官方题目的地址11.盛最多水的容器给定一个长度为n的整数数组height。有n条垂线,第i条线的两个端点是(i,0)和(i,height[i])。找出其中的两条线,使得它们与x轴共同构成的容器可以容纳最多的......