1. 题目描述
输入:obstacleGrid = [[0,0,0],[0,1,0],[0,0,0]]
输出:2
解释:
3x3 网格的正中间有一个障碍物。
从左上角到右下角一共有 2 条不同的路径:
1. 向右 -> 向右 -> 向下 -> 向下
2. 向下 -> 向下 -> 向右 -> 向右
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/unique-paths-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2. 解法
思路:动态规划。
动规五部曲:
-
确定dp数组(dp table)以及下标的含义
dp[i][j]:到第i行第j列的路径总数;
-
确定递推公式
当没遇到障碍物时,dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
当遇到障碍物时:不作处理,直接continue到下一循环。
-
dp数组如何初始化
当一行或者一列中有障碍物,那么直接dp[i][0] = dp[0][i] = 0;
否则为1
-
确定遍历顺序
从小到大遍历
-
举例推导dp数组
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
int m = obstacleGrid.size();
int n = obstacleGrid[0].size();
vector<vector<int>>dp (m, vector<int> (n, 0));
for(int i = 0; i < m && obstacleGrid[i][0] == 0 ; ++i)
dp[i][0] = 1;
for(int i = 0; i < n && obstacleGrid[0][i] == 0; ++i)
dp[0][i] = 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];
}
}
return dp[m - 1][n - 1];
}
举例 当obstacleGrid = [[0,0,0],[0,1,0],[0,0,0]] 时,dp数组如下:
1 | 1 | 1 |
---|---|---|
1 | 0 | 1 |
1 | 1 | 2 |
中间的0表示直接跳过此格计算,因为不能经过此格。