返回
LeetCode 题解:63. 不同路径 II,JavaScript 详细教程,动态规划
前端
2023-10-17 13:25:15
众所周知,动态规划算法是一项重要且常见的编程技巧,在各种算法问题中有着广泛的应用,而 LeetCode 则是备受程序员青睐的编程题网站。因此,掌握 LeetCode 中的动态规划问题不仅能够提升你的算法能力,还能让你在面试中脱颖而出。
今天,我们将着眼于 LeetCode 上的第 63 道题目:不同路径 II。在这道题中,你将面对一个包含障碍物的网格,需要计算从网格左上角走到右下角的不同路径数量。
问题 :
在一个大小为 m x n 的网格中,每个单元格可以是以下三种状态之一:
- 可通行:你可以通过这个单元格。
- 障碍物:你无法通过这个单元格。
- 起点:你只能从这个单元格开始移动。
- 终点:你只能在这个单元格结束移动。
你需要计算从起点走到终点有多少条不同的路径。如果从起点到终点不存在路径,则返回 0。
动态规划解法:
动态规划是一种自底向上的解题方法,它将问题分解成一系列子问题,然后逐步解决这些子问题,最终得到整个问题的解。对于 LeetCode 63. 不同路径 II,我们可以使用动态规划的思想来解决问题。
具体步骤如下:
-
定义动态规划状态 :
设
dp[i][j]
表示从网格左上角走到单元格(i, j)
的不同路径数量。 -
边界条件 :
- 对于障碍物单元格,即
grid[i][j] == 1
,则dp[i][j] = 0
。 - 对于第一行和第一列的单元格,由于它们只能从一个方向移动,因此
dp[i][0] = 1
和dp[0][j] = 1
。 - 对于起点单元格,由于它只能从一个方向移动,因此
dp[0][0] = 1
。
- 对于障碍物单元格,即
-
动态规划递推公式 :
对于非障碍物单元格,即
grid[i][j] == 0
,则dp[i][j]
可以从上面和左面的单元格转移而来,因此:dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
-
返回结果 :
最终,问题的解即为
dp[m - 1][n - 1]
。
代码实现 :
/**
* @param {number[][]} grid
* @return {number}
*/
const uniquePathsWithObstacles = (grid) => {
if (grid[0][0] === 1) {
return 0;
}
const m = grid.length;
const n = grid[0].length;
const dp = new Array(m).fill(0).map(() => new Array(n).fill(0));
dp[0][0] = 1;
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
if (grid[i][j] === 1) {
dp[i][j] = 0;
} else if (i === 0 || j === 0) {
dp[i][j] = 1;
} else {
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
}
}
}
return dp[m - 1][n - 1];
};
复杂度分析 :
- 时间复杂度:O(m * n),其中 m 和 n 分别为网格的长和宽。
- 空间复杂度:O(m * n),其中 m 和 n 分别为网格的长和宽。
通过这个详细的 JavaScript 代码示例,你将彻底理解如何使用动态规划算法来解决 LeetCode 题库中的不同路径 II 这类问题。如果你想进一步深入学习动态规划,可以搜索其他相关的编程教程和资源,不断提升自己的算法能力。