leetCode动态规划“不同路径II”
迷宫问题是比较经典的算法问题,一般可以用动态规划、回溯等方法进行解题,这道题目是我昨晚不同路径这道题趁热打铁继续做的,思路与原题差不多,只是有需要注意细节的地方,那么话不多说,直接上coding和解析!
题目描述
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish”)。
现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?
网格中的障碍物和空位置分别用 1 和 0 来表示。
解析
如果做过类似迷宫问题的读者,对于这道题目的思路想必也会第一时间想到仍然使用动态规划的思路去解答,但是对于路径中的障碍物在这里却需要着重的单独讨论,因为有了障碍物,那么对于部分目标点的路径数会发生改变。此题目中需要考虑的特殊位置有如下图所示;
所画图给出了一种情况下的各个点下的路径数,可以看到,对于紫色笔给出的新的当前的节点路径数,仍满足原始状态下的dp[i][j] = dp[i-1][j]+dp[i][j-1]的动态递推式(但对于有障碍的节点不满足,那么障碍节点可达到路径数直接为0),对于迷宫问题,当前节点的可通行路线是由当前节点的左侧节点和正上方节点的可通过路径数相加得到,那对于左上方存在障碍的情况,当前节点的可通过数就需要变化。如下图所示。
这是相对于原始题目的第一处变化,考虑了障碍物,那么就得讨论一下障碍物在某些特殊位置下的特殊情况,比如障碍物在初始行、列上的时候,比如:
这种情况下,我们就不能单纯的只能把障碍物所处的位置上的路径数置为0,而是要把往后的那一列/一行上的数据都要置为0,为什么,因为机器人只能向下或者向右走,所以,对于初始行、列上的障碍物往后的点,机器人是无法到达的!!!
当然,还剩下最后一个情况,起点就有障碍物,那直接return 0咯~
代码
1.初始化dp数组
//初始化dp数组,我这里全给的-1,方便后续判别障碍物、无障碍物和路径数
int dp[110][110];for(int i=0;i<110;i++){for(int j =0;j<110;j++){dp[i][j] = -1;}}
2.根据地图,将地图中障碍物所处对应的dp数组位置置路径数为0
for(int i=0;i<obstacleGrid.size();i++){for(int j=0;j<obstacleGrid[i].size();j++){if(i == 0 && j ==0){//起点是障碍物if(obstacleGrid[i][j] == 1){return 0;}}if(i == 0){//障碍物在初始行上if(obstacleGrid[i][j] == 1){for(int m = j;m<obstacleGrid[i].size();m++){dp[i][m] = 0;}}}if(j == 0){//障碍物在初始列上if(obstacleGrid[i][j] == 1){dp[i][j] = 0;for(int x = i+1;x<obstacleGrid.size();x++){dp[x][j] = 0;}}}else if(i != 0 && j!= 0){//障碍物不在特殊位置上,那直接对应位置dp设置为0即可if(obstacleGrid[i][j] == 1){dp[i][j] = 0;}}}}
3.计算dp数组
for(int i=0;i<obstacleGrid.size();i++){for(int j=0;j<obstacleGrid[i].size();j++){if(i == 0 || j == 0){if(dp[i][j] == -1){dp[i][j] = 1;}}if(i != 0 && j != 0){if(dp[i][j] != 0){dp[i][j] = dp[i-1][j] + dp[i][j-1];}}}}
4. 完整代码和结果
class Solution {
public:int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {// 跟第一种情况是一样的,只是对于地图中有障碍物的地方,对应的dp数组置为1int dp[110][110];for(int i=0;i<110;i++){for(int j =0;j<110;j++){dp[i][j] = -1;}}for(int i=0;i<obstacleGrid.size();i++){for(int j=0;j<obstacleGrid[i].size();j++){if(i == 0 && j ==0){if(obstacleGrid[i][j] == 1){return 0;}}if(i == 0){if(obstacleGrid[i][j] == 1){for(int m = j;m<obstacleGrid[i].size();m++){dp[i][m] = 0;}// break;}}if(j == 0){if(obstacleGrid[i][j] == 1){dp[i][j] = 0;for(int x = i+1;x<obstacleGrid.size();x++){dp[x][j] = 0;}// break;}}else if(i != 0 && j!= 0){if(obstacleGrid[i][j] == 1){dp[i][j] = 0;}}}}for(int i=0;i<obstacleGrid.size();i++){for(int j=0;j<obstacleGrid[i].size();j++){if(i == 0 || j == 0){if(dp[i][j] == -1){dp[i][j] = 1;}}if(i != 0 && j != 0){if(dp[i][j] != 0){dp[i][j] = dp[i-1][j] + dp[i][j-1];}}// else{// dp[i][j] = dp[i-1][j] + dp[i][j-1];// }}}cout<<dp[obstacleGrid.size()-1][obstacleGrid[0].size()-1];return dp[obstacleGrid.size()-1][obstacleGrid[0].size()-1];}
};
总结
个人感觉,这类题目是十分具有代表性的动态规划算法题 ,为什么这么说,因为动态规划要满足最优子结构,而恰恰这类题的子结构十分清晰,就比如我要知道当前位置有几种路径可以到达,就可以直接从我的前一步,也就是我的左边那一步和正上面的那一步就能到达,也就是我的左边和上面是与我当前可联通的,那么就直接得到了我当前的可通行路径数。有的人可能会说,那这样的话,应该是两者之和再加1才是最终的路径数呀?
其实不然,我最开始也陷入了这样的思维模式中去了,而其实应该这么想,我们所要求的是路径,而不是步数,讨论的不是走了几步,而是有几种到达的方法,换言之就是,只要我能到达左边那个位置或者上面那个位置,那么我一定能够到达当前所求的这个位置,那么也就说明,到达上面/左边位置的路径均能到达我当前的位置,那么两个地方的路径数之和就是到达当前位置的路径数之和~ 这里就不贴图了 ,如果文字描述不清楚,可以结合上面的xyz那张图(也就是所有图中的第三张图)进行结合理解。
动态规划变种很多,前些时候做了些公司面试笔试题 ,发现很多题可以用动态规划来做,但是不得其解,文中的题目是比较清晰的,容易推出动态规划递推式的类型,对于一些变种,还需要多做多总结!欢迎各位读者在评论区进行讨论,有更好的方法我也很愿意与您交流学习!
如果文章对您有帮助,可以点个小赞哦~
相关文章:

leetCode动态规划“不同路径II”
迷宫问题是比较经典的算法问题,一般可以用动态规划、回溯等方法进行解题,这道题目是我昨晚不同路径这道题趁热打铁继续做的,思路与原题差不多,只是有需要注意细节的地方,那么话不多说,直接上coding和解析&a…...

100天精通Python(可视化篇)——第99天:Pyecharts绘制多种炫酷K线图参数说明+代码实战
文章目录 专栏导读一、K线图介绍1. 说明2. 应用场景 二、配置说明三、K线图实战1. 普通k线图2. 添加辅助线3. k线图鼠标缩放4. 添加数据缩放滑块5. K线周期图表 书籍推荐 专栏导读 🔥🔥本文已收录于《100天精通Python从入门到就业》:本专栏专…...

哈希表与有序表
哈希表与有序表 Set结构 key Map结构 key-value 哈希表 哈希表的时间复杂度都是常数项级别的,但常数较大 增删改查的时间都是常数级别的,与数据量无关 当哈希表存储的值是基础数据类型(Integer - int),哈希表中内…...
什么时候使用RPA?如何使用RPA?需要什么样的硬件支持?需要安装哪些软件?
RPA(Robotic Process Automation)是一种用于自动化执行重复性任务的技术,它可以帮助企业提高工作效率,降低人力成本,并减少人为错误。RPA适用于各种行业和场景,例如财务、人力资源、客户服务、IT运维等。 …...

R语言入门——line和lines的区别
目录 0 引言一、 line()二、 lines() 0 引言 首先,从直观上看,lines比line多了一个s,但它们还是有很大的区别的,下面将具体解释这个两个函数的区别。 一、 line() 从R语言的帮助文档中找到,line()的使用,…...

C语言:static关键字的使用
1.static修饰局部变量 这是static关键字使用最多的情况。我们知道局部变量是在程序运行阶段在栈上创建的,但是static修饰的局部变量是在程序编译阶段在代码段(静态区)创建的。所以在static修饰的变量所在函数执行结束后该变量依然存在。 //…...
AUTOSAR知识点 之 ECUM (三):ECUM的ISOLAR-AB配置及代码解析
目录 1、概述 2、ISOLAR-AB配置 2.1、EcuMGeneral 2.2、EcuMConfiguration 2.2.1、EcuMDefaultShutdownTarget 2.2.2、EcuMDriverInitListOne...

2023年MySQL-8.0.34保姆级安装教程
重点放前面:演示环境为windows环境。 MySQL社区版本安装教程如下: 一、MySQL安装包下载二、安装配置设置三、配置环境变量 大体分为3个步骤:①安装包的下载;②安装配置设置;③配置环境变量 一、MySQL安装包下载 下载官…...

ElasticSearch入门
一、基本命令_cat 1、查看节点信息 http://192.168.101.132:9200/_cat/nodes2、查看健康状况 http://192.168.101.132:9200/_cat/health3、查看主节点的信息 http://192.168.101.132:9200/_cat/master4、查看所有索引 http://192.168.101.132:9200/_cat/indices二、索引一…...
RocketMQ的Broker
1 Broker角色 Broker角色分为ASYNC_MASTER (异步主机)、SYNC_MASTER (同步主机)以及SLAVE (从机)。如果对消息的可靠性要求比较严格,可以采用SYNC_MASTER加SLAV E的部署方式。如果对消息可靠性要求不高,可以采用ASYNC_MASTER加ASL AVE的部署方式。如果只…...

使用Puppeteer进行游戏数据可视化
导语 Puppeteer是一个基于Node.js的库,可以用来控制Chrome或Chromium浏览器,实现网页操作、截图、测试、爬虫等功能。本文将介绍如何使用Puppeteer进行游戏数据的爬取和可视化,以《英雄联盟》为例。 概述 《英雄联盟》是一款由Riot Games开…...

【Flask】from flask_sqlalchemy import SQLAlchemy报错
【可能出现的情况】 1、未安装 Flask-SQLAlchemy: 在使用 flask_sqlalchemy 之前,你需要确保已经通过 pip 安装了 Flask-SQLAlchemy。可以通过以下命令安装它: pip install Flask-SQLAlchemy 2、包名大小写问题: Python 是区分大…...

索引简单概述(SQL)
一、什么是索引? 索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),他们包含着对数据表里所有记录的引用指针。 索引是一种数据结构。数据库索引,是数据库管理系统中一个排序的数据结构࿰…...
union all 和 union 的区别,mysql union全连接查询
602. 好友申请 II :谁有最多的好友(力扣mysql题,难度:中等) RequestAccepted 表: ------------------------- | Column Name | Type | ------------------------- | requester_id | int | | accepter_id | int | | accept_date …...
UDP和TCP的区别
UDP (User Datagram Protocol) 和 TCP (Transmission Control Protocol) 是两种常见的传输层协议。它们在设计和用途上有很大的区别,以下是它们的主要差异: 连接性: TCP: 是一个连接导向的协议。它首先需要建立连接,数据传输完毕后再终止连接…...

阿里云 MSE 助力开迈斯实现业务高增长背后带来的服务挑战
开迈斯新能源科技有限公司于 2019 年 5 月 16 日成立,目前合资股东分别为大众汽车(中国)投资有限公司、中国第一汽车股份有限公司、一汽-大众汽车有限公司[增资扩股将在取得适当监督(包括反垄断)审批后完成]、万帮数字…...

消灭怪物的最大数量【力扣1921】
一、题目分析 需要满足的条件: 只能在每分钟的开始使用武器武器能杀死距离城市最近的怪兽怪兽到达城市就会输掉游戏 游戏最优策略:我们可以在每分钟的开始都使用一次武器,用来杀死距离城市最近的怪兽。这样可以在力所能及的范围内…...
数据结构之算法
算法的基本概念 计算机解题的过程实际上是在实施某种算法,这种算法称为计算机算法 算法的基本要素 一个算法是由两种基本要素组成:一是对数据对象的运算和操作;二是算法的控制结构 算法中对数据的运算和操作 在一般计算机系统中…...
MyBatis与MyBatis-Plus的分页以及转换
一、介绍 MyBatis和MyBatis-Plus都是Java持久化框架,用于简化数据库访问和操作。它们提供了面向对象的方式来管理关系型数据库中的数据。 MyBatis是一个轻量级的持久化框架,通过XML或注解配置,将SQL语句与Java对象进行映射,使开…...
TCP/IP网络编程(二) 套接字协议及其数据传输特性
文章目录 套接字协议及其数据传输特性关于协议创建套接字协议族套接字类型1:面向连接的套接字(SOCK_STREAM)套接字类型2:面向消息的套接字(SOCK_DGRAM)协议的最终选择面向连接的套接字:TCP套接字…...
<6>-MySQL表的增删查改
目录 一,create(创建表) 二,retrieve(查询表) 1,select列 2,where条件 三,update(更新表) 四,delete(删除表…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...
大模型多显卡多服务器并行计算方法与实践指南
一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...
什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南
文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...
怎么让Comfyui导出的图像不包含工作流信息,
为了数据安全,让Comfyui导出的图像不包含工作流信息,导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo(推荐) 在 save_images 方法中,删除或注释掉所有与 metadata …...
uniapp 实现腾讯云IM群文件上传下载功能
UniApp 集成腾讯云IM实现群文件上传下载功能全攻略 一、功能背景与技术选型 在团队协作场景中,群文件共享是核心需求之一。本文将介绍如何基于腾讯云IMCOS,在uniapp中实现: 群内文件上传/下载文件元数据管理下载进度追踪跨平台文件预览 二…...

【若依】框架项目部署笔记
参考【SpringBoot】【Vue】项目部署_no main manifest attribute, in springboot-0.0.1-sn-CSDN博客 多一个redis安装 准备工作: 压缩包下载:http://download.redis.io/releases 1. 上传压缩包,并进入压缩包所在目录,解压到目标…...
数据库正常,但后端收不到数据原因及解决
从代码和日志来看,后端SQL查询确实返回了数据,但最终user对象却为null。这表明查询结果没有正确映射到User对象上。 在前后端分离,并且ai辅助开发的时候,很容易出现前后端变量名不一致情况,还不报错,只是单…...