一、63. 不同路径 II
1.题目描述
一个机器人位于一个 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
2.解题思路
- 在对第一行,第一列dp数组初始化的时候,如果遇到障碍,那么后面的也就无法通过了,因此后面的dp值都是0
- 在遍历dp时,如果遇到了障碍,就直接continue
3.代码实现
class Solution {
public:
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
//1.明确dp数组的含义:从(0,0)到(i,j)有dp[i][j]种方法
//2.明确递推公式:题目要求,只能往下或者右 移动,
//因此每个网格的抵达方法要么就是从上面的往下移动一步,要么就是从左边的往右移动一步
//3.如何初始化。第一行和第一列是无法从左边或者从上面移动下来的,因此需要单独初始化
//4.什么遍历顺序? 从左往右,从上往下
int m = obstacleGrid.size();
int n = obstacleGrid[0].size();
//如果障碍在起点或者在终点,直接return 0
if(obstacleGrid[0][0] == 1 || obstacleGrid[m-1][n-1] == 1)
return 0;
vector<vector<int>> dp(m,vector(n,0));
//开始对dp初始化
//对第一行赋初值
for(int i = 0;i < n && obstacleGrid[0][i] == 0;i++)//遇到障碍,后面的路也无法通过
dp[0][i] = 1;
//对第一列赋初值
for(int i = 0;i < m && obstacleGrid[i][0] == 0;i++)
dp[i][0] = 1;
//开始遍历
for(int i = 1;i < m;i++){
for(int j = 1;j < n;j++){
//如果当前网格中是障碍,直接跳过赋值,
if(obstacleGrid[i][j] == 1)
continue;
//否则,进行递推公式
dp[i][j] = dp[i-1][j] + dp[i][j-1];
}
}
//返回终点的dp值
return dp[m-1][n-1];
}
};