IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 63. 不同路径 II【动态规划】 -> 正文阅读

[数据结构与算法]63. 不同路径 II【动态规划】

63.不同路径 II

题目链接:https://leetcode-cn.com/problems/unique-paths-ii/

一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。
现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?

?

网格中的障碍物和空位置分别用 1 和 0 来表示。
示例 1:

输入:obstacleGrid = [[0,0,0],[0,1,0],[0,0,0]]
输出:2
解释:
3x3 网格的正中间有一个障碍物。
从左上角到右下角一共有 2 条不同的路径:
1.?向右 -> 向右 -> 向下 -> 向下
2.?向下 -> 向下 -> 向右 -> 向右

示例 2:

输入:obstacleGrid = [[0,1],[0,0]]
输出:1

提示:
*?m ==?obstacleGrid.length
*?n ==?obstacleGrid[i].length
*?1 <= m, n <= 100
*?obstacleGrid[i][j]为 0 或 1

思路

这道题相对于62.不同路径就是有了障碍。

第一次接触这种题目可能会有点懵,这如果有障碍了,应该怎么算呢?

62.不同路径中已经详细分析了没有障碍的情况,有障碍的话,其实就是标记对应的dp table(dp数组)保持初始值(0)就可以了。

动规五部曲:

1.确定dp数组(dp table)以及下标的含义

dp[i][j]?:表示从(0 ,0)出发,到(i, j) 有dp[i][j]条不同的路径。

2.确定递推公式

递推公式和62.不同路径一样,dp[i][j]=?dp[i - 1][j]+?dp[i][j - 1]。

但这里需要注意一点,因为有了障碍,(i, j)如果就是障碍的话应该就保持初始状态(初始状态为0)。


所以代码为:

```
if (obstacleGrid[i][j] == 0) { // 当(i, j)没有障碍的时候,再推导dp[i][j]
????dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
}
```

3.dp数组如何初始化

62.不同路径不同路径中我们给出如下的初始化:

```
for (int i = 0; i < m; i++) dp[i][0] = 1;
for (int j = 0; j < n; j++) dp[0][j] = 1;
```

因为从(0, 0)的位置到(i, 0)的路径只有一条,所以dp[i][0]一定为1,dp[0][j]也同理。

但如果(i, 0) 这条边有了障碍之后,障碍之后(包括障碍)都是走不到的位置了,所以障碍之后的dp[i][0]应该还是初始值0。

如图:

?

下标(0, j)的初始化情况同理。

所以本题初始化代码为:

```
for (int i = 0; i < m && obstacleGrid[i][0] == 0; i++) dp[i][0] = 1;
for (int j = 0; j < n && obstacleGrid[0][j] == 0; j++) dp[0][j] = 1;
```

注意代码里for循环的终止条件,一旦遇到obstacleGrid[i][0] == 1的情况就停止dp[i][0]的赋值1的操作,dp[0][j]同理

4.?确定遍历顺序

从递归公式dp[i][j]?=?dp[i - 1][j]?+ dp[i][j - 1]?中可以看出,一定是从左到右一层一层遍历,这样保证推导dp[i][j]的时候,dp[i - 1][j]?和 dp[i][j - 1]一定是有数值。

代码如下:

```
for (int i = 1; i < m; i++) {
????for (int j = 1; j < n; j++) {
????????if (obstacleGrid[i][j] == 1) continue;
????????dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
????}
}
```

5.?举例推导dp数组

拿示例1来举例如题:


对应的dp table 如图:


如果这个图看不同,建议在理解一下递归公式,然后照着文章中说的遍历顺序,自己推导一下?!?

动规五部分分析完毕,对应java代码如下:

?

什么是动态规划

动态规划,英?:Dynamic Programming,简称DP,如果某?问题有很多重叠?问题,使?动态规划是最有效的。

动态规划中每?个状态?定是由上?个状态推导出来的,这?点就区分于贪?,贪?没有状态推导,?是从局部直接选最优的。

动规和贪心的区别举个例子:

例如:有N件物品和?个最多能背重量为W 的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品只能??次,求解将哪些物品装?背包?物品价值总和最?。

动态规划中dp[j]是由dp[j-weight[i]]推导出来的,然后取max(dp[j], dp[j - weight[i]] + value[i])。

但如果是贪?呢,每次拿物品选?个最?的或者最?的就完事了,和上?个状态没有关系。?

动态规划的解题步骤:

对于动态规划问题,可以拆解为如下五步曲,这五步都搞清楚了,才能说把动态规划真的掌握了!

  1. 确定dp数组(dp table)以及下标的含义
  2. 确定递推公式
  3. dp数组如何初始化
  4. 确定遍历顺序
  5. 举例推导dp数组
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-09-10 11:06:46  更:2021-09-10 11:08:44 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/30 1:17:56-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码