本文已参与「新人创作礼」活动,一起开启掘金创作之路。
不同路径 II
63. 不同路径 II - 力扣(LeetCode) (leetcode-cn.com)
一个机器人位于一个 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
解题思路
将所有的障碍物设置为0,每遍历到一个格子的时候,只需要将此格子的上面格子和左边格子的路径相加,就是机器人到达此格子的路径个数。
代码思想为三步:
- 因为矩阵的第一行没有上格子,矩阵的第一列没有左格子。所有需要单独遍历。这里需要注意:只要出现一个障碍物,那么这一行或者这一列障碍物后面的格子机器人都无法到达。
- 遍历除去第一行和第一列的所有格子,计算路径个数。
- 返回矩阵的最后一个元素。
代码实现
class Solution {
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
int m = obstacleGrid.length,n = obstacleGrid[0].length;
if(obstacleGrid[0][0]==1 || obstacleGrid[m-1][n-1]==1)return 0;
if(n==1) return obstacleGrid[0][0]==1?0:1;
//flag表示第一列只要有一个障碍,那么以后的格子都没有路径可到达
int flag=0;
for(int i=1 ; i<m;i++){
if(obstacleGrid[i][0]==1) {
obstacleGrid[i][0]=0;
flag=1;
}
if(flag!=1) obstacleGrid[i][0]=1;
}
//flag1表示第一行只要有一个障碍,那么以后的格子都没有路径可到达
int flag1=0;
for(int i=1 ; i<n;i++){
if(obstacleGrid[0][i]==1) {
obstacleGrid[0][i]=0;
flag1=1;
}
if(flag1!=1) obstacleGrid[0][i]=1;
}
//遍历其他的格子
for(int i = 1; i<m;i++){
for(int j = 1; j<n;j++){
//若格子为障碍物,则设置路径个数为0,若不是障碍物,就将左格子和上格子的路径个数相加。
if(obstacleGrid[i][j] == 1) {
obstacleGrid[i][j] = 0;
}else{
obstacleGrid[i][j] = obstacleGrid[i][j-1]+obstacleGrid[i-1][j];
}
}
}
return obstacleGrid[m-1][n-1];
}
}
参考
63. 不同路径 II 有障碍物(详细C++思路分析+解题步骤) - 不同路径 II - 力扣(LeetCode) (leetcode-cn.com)