一个机器人位于一个 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
解题思路
- 有障碍物
- 主要是初始化的时候麻烦
- 递推过程一样
- 初始化障碍物的网格
- 第一个位置
dp[0][0] = 1 ;
- 初始化行列
- 需要判断
if (obstacleGrid[0][c] != 1)- 如果遇到石头,走不通,用默认0
- 如果不是石头,就取前面的值,所以如果前面的阻塞了,后面的也都走不通
- 需要判断
- 第一个位置
- 动态递推
- 遍历
/*** @param {number[][]} obstacleGrid* @return {number}*/var uniquePathsWithObstacles = function (obstacleGrid) {if (obstacleGrid[0][0] == 1) return 0; // 出发点就被障碍堵住const rows = obstacleGrid.length; // 行const cols = obstacleGrid[0].length; // 列// 初始化// map无法遍历空的,要么就要用for循环const dp = new Array(rows).fill(0).map(() => new Array(cols).fill(0));// base casedp[0][0] = 1;// 第一行for (let c = 1; c < cols; c++) {// 只要当前不是障碍物,值就是1// 遇到障碍物,之后的都不会赋值为1了if (obstacleGrid[0][c] != 1) {dp[0][c] = dp[0][c - 1];}}// 第一列for (let r = 1; r < rows; r++) {if (obstacleGrid[r][0] != 1) {dp[r][0] = dp[r - 1][0];}}// 动态递推for (var r = 1; r < rows; r++) {for (var c = 1; c < cols; c++) {// 遇到障碍物不能走if (obstacleGrid[r][c] != 1) {dp[r][c] = dp[r - 1][c] + dp[r][c - 1];}}}return dp[rows - 1][cols - 1];};
