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 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 【算法-LeetCode】62. 不同路径(动态规划;滚动数组) -> 正文阅读

[数据结构与算法]【算法-LeetCode】62. 不同路径(动态规划;滚动数组)

62. 不同路径 - 力扣(LeetCode)

发布:2021年9月23日22:06:07

问题描述及示例

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

示例 1:

输入:m = 3, n = 7
输出:28

示例 2:
输入:m = 3, n = 2
输出:3
解释:
从左上角开始,总共有 3 条路径可以到达右下角。

  1. 向右 -> 向下 -> 向下
  2. 向下 -> 向下 -> 向右
  3. 向下 -> 向右 -> 向下


示例 3:
输入:m = 7, n = 3
输出:28

示例 4:
输入:m = 3, n = 3
输出:6

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/unique-paths
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

提示:
1 <= m, n <= 100
题目数据保证答案小于等于 2 * 109

我的题解(动态规划)

有关动态规划的思路总结,之前写过一个相关的题解博客:

参考:【算法-LeetCode】53. 最大子序和(动态规划初体验)_赖念安的博客-CSDN博客

里面也有我写的其他动态规划题解,一些通用的步骤都是一样的,也可以作为参考,进行对照思考。

而本题的思路和我之前做的一个动态规划题目非常像:

参考:【算法-LeetCode】64. 最小路径和(动态规划;二维数组;滚动数组)_赖念安的博客-CSDN博客

两道题目都有共同的特点:dp[i][j] 的值都是由其相邻的正上方元素(dp[i-1][j])和相邻的正左方元素(dp[i][j-1])决定的。所以两者的动态转移方程也有相似之处。

我的题解1(二维dp数组)

在本题中,dp[i][j] 代表由起点(也就是点 [0,0])到点 [i][j] 有几条可行的路径(当然,按照题目要求只能向下或想右走)。

具体的分析步骤就不赘述了,和上面那道题的基本一样,只要根据我之前总结的那几个步骤一点点分析即可。说一下本题的总体核心思路:我们要走到点 [i][j] ,只能先到达其正上方或者正左方,所以只要知道到达 [i-1][j][i][j-1] 各有几条符合条件的路径,再将两者相加即可得到到达 [i][j] 总共有几条路径。

经过上面的总体分析,动态转移方程也能很快就写出来:dp[i][j] = dp[i-1][j] + dp[i][j-1]

而由动态转移方程可知,我们必须先初始化 dp 数组的第一行和第一列。

详细解释请看下方注释:

/**
 * @param {number} m
 * @param {number} n
 * @return {number}
 */
var uniquePaths = function(m, n) {
  // 创建一个 m × n 的二维dp数组,并给每个元素都事先填充为1
  let dp = Array.from({length: m}).map(
    () => Array.from({length: n}).fill(1)
  );
  // 因为上面创建dp数组时其实就已经顺便完成了对dp数组第一行和第一列的初始化操作
  // 所以这里就不用再特意初始化dp数组了,直接对 m x n 的网格进行由前到后的遍历
  for(let i = 1; i < m; i++) {
    for(let j = 1; j < n; j++) {
      // dp[i][j]的值由其相邻的上方和相邻的左方元素推导出来
      dp[i][j] = dp[i-1][j] + dp[i][j-1];
    }
  }
  // 最后返回dp数组右下角的元素即可
  return dp[m-1][n-1];
};


提交记录
执行结果:通过
62 / 62 个通过测试用例
执行用时:76 ms, 在所有 JavaScript 提交中击败了47.14%的用户
内存消耗:37.8 MB, 在所有 JavaScript 提交中击败了69.82%的用户
时间:2021/09/23 22:12

其实这道题的动态转移方程比较好推断,关键是要想明白 dp[i][j] 的含义。

或者说,我们得先想明白怎样定义 dp[i][j] ,才能用上动态规划的思路,我觉得这才是所有动态规划类型的题目的关键所在。

我的题解2(一维dp数组)

当然,这道题用到了二维的 dp 数组,而其实这里也能利用滚动数组的操作来把二维数组降为一维数组,从而降低空间消耗。有关滚动数组的过程我也在相关的博客中有提到,只是这个概念比较难用语言描述,最好还是通过观察实际的二维表格到压缩到一维表格的过程来理解才有更好的效果。

参考:【算法-LeetCode】322. 零钱兑换(动态规划;博采众长的完全背包问题详解;二维数组;滚动数组)_赖念安的博客-CSDN博客
参考:【算法-LeetCode】64. 最小路径和(动态规划;二维数组;滚动数组)_赖念安的博客-CSDN博客

/**
 * @param {number} m
 * @param {number} n
 * @return {number}
 */
var uniquePaths = function(m, n) {
  let dp = Array.from({length: n}).fill(1);
  for(let i = 1; i < m; i++) {
    for(let j = 1; j < n; j++) {
      dp[j] = dp[j] + dp[j-1];
    }
  }
  return dp[n-1];
};


提交记录
执行结果:通过
62 / 62 个通过测试用例
执行用时:68 ms, 在所有 JavaScript 提交中击败了80.40%的用户
内存消耗:37.5 MB, 在所有 JavaScript 提交中击败了95.08%的用户
时间:2021/09/23 23:23	

可以看到,使用一维 dp 数组的时间和空间性能都显著提升了。但是其核心的思路还是不变的,只不过是重复利用了某一个一维数组。而我们可以重复利用这个数组的最关键因素就是:除了需要初始化的那些 dp 元素,其余所有的 dp[i][j] 都是通过其“前面”的元素计算得到的,或者说新的 dp[i][j] 会覆盖前一轮计算得到的 dp[i][j] ,所以一维数组中的某一个位置能够被重复利用。

基本上所有的二维 dp 数组都可以通过上面的思路化为一维数组。所以我觉得在研究一维 dp 数组(滚动数组)前,应该先对二维的实现原理有充分的理解。

官方题解

更新:2021年7月29日18:43:21

因为我考虑到著作权归属问题,所以【官方题解】部分我不再粘贴具体的代码了,可到下方的链接中查看。

更新:2021年9月23日22:14:29

参考:不同路径 - 不同路径 - 力扣(LeetCode)

【更新结束】

有关参考

更新:2021年9月22日14:08:16
参考:【算法-LeetCode】53. 最大子序和(动态规划初体验)_赖念安的博客-CSDN博客
更新:2021年9月23日22:15:04
参考:【算法-LeetCode】64. 最小路径和(动态规划;二维数组;滚动数组)_赖念安的博客-CSDN博客
参考:【算法-LeetCode】322. 零钱兑换(动态规划;博采众长的完全背包问题详解;二维数组;滚动数组)_赖念安的博客-CSDN博客

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-09-24 10:50:25  更:2021-09-24 10:51:16 
 
开发: 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年11日历 -2024/11/26 4:48:13-

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