携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第29天,点击查看活动详情
63. 不同路径 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
解题思路
// 第一种
动态规划:
状态dp[i][j]表示到达n=i,m=j这个位置一共有几种方法,遇到障碍物就为0
dp[0][0] = 1
状态转方程:
没有障碍物,dp[i][j] = dp[i][j-1] + dp[i-1][j]
有障碍物,dp[i][j] = 0
// 第二种
既然是障碍物,说明此路不通,即经过此节点的路径数为0,所以当遇到障碍物时,设置dp[i][r] = 0即可
那么第一行第一列数据初始化的时候就不能都是1了,因为有的地方有障碍物存在
初始化dp二维数组的时候各个节点都不可达
这样dp递推的时候,只需要在62题的基础上加上obstacleGrid[i][r]当前节点不为障碍物的条件即可
而有障碍物的地方为0,加0也就等于没走
代码实现
// 第一种
var uniquePathsWithObstacles = function(obstacleGrid) {
let row = obstacleGrid.length
let col = obstacleGrid[0].length //obstacleGrid数组长度
let dp = Array.from(new Array(row), ()=>new Array(col).fill(0))
//初始化
if(obstacleGrid[0][0] == 0){
dp[0][0]=1
}
for(let i=1; i<row; i++){
if(obstacleGrid[i][0] == 0){
dp[i][0] = dp[i-1][0]
}
}
for(let j=1; j<col; j++){
if(obstacleGrid[0][j] == 0){
dp[0][j] = dp[0][j-1]
}
}
for(let i=1; i<row; i++){
for(let j=1; j<col; j++){
if(obstacleGrid[i][j] == 0){
dp[i][j] = dp[i][j-1] + dp[i-1][j]
}
}
}
return dp[row-1][col-1]
};
// 第二种
/**
* @param {number[][]} obstacleGrid
* @return {number}
*/
var uniquePathsWithObstacles = function(obstacleGrid) {
// 行
var n = obstacleGrid.length;
// 列
var m = obstacleGrid[0].length;
// 初始化
var dp = new Array(n);
for(var i = 0;i<n;i++){
dp[i] = new Array(m).fill(0);
}
dp[0][0] = obstacleGrid[0][0] == 0 ? 1 : 0;
// 如果起点就是障碍物
if(dp[0][0] == 0){
return 0 ;
}
// 第一行
for(var j = 1;j < m;j++){
if(obstacleGrid[0][j] != 1){
dp[0][j] = dp[0][j-1];
}
}
// 第一列
for(var r = 1;r < n;r++){
if(obstacleGrid[r][0] != 1){
dp[r][0] = dp[r-1][0];
}
}
// 动态递推
for(var i = 1;i < n;i++){
for(var r = 1;r < m;r++){
if(obstacleGrid[i][r] != 1){
dp[i][r] = dp[i-1][r] +dp[i][r-1];
}
}
}
return dp[n-1][m-1];
};
如果你对这道题目还有疑问的话,可以在评论区进行留言;