题目
一个机器人位于一个
m
∗
n
m * n
m∗n 网格的左上角。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角。现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?
网格中的障碍物和空位置分别用 1 和 0 来表示。
思路
- 刚开始想用回溯递归,但是时间太久了
- 官方题解使用动态规划
- 来自官方题解的一句话
- 动态规划的题目分为两大类,一种是求最优解类,典型问题是背包问题,另一种就是计数类,比如这里的统计方案数的问题,它们都存在一定的递推性质。前者的递推性质还有一个名字,叫做 「最优子结构」 ——即当前问题的最优解取决于子问题的最优解,后者类似,当前问题的方案数取决于子问题的方案数。所以在遇到求方案数的问题时,我们可以往动态规划的方向考虑。
- 到达 ( i , j ) (i,j) (i,j) 处的路径数为到达 ( i − 1 , j ) , ( i , j − 1 ) (i-1,j),(i,j-1) (i−1,j),(i,j−1) 路径数的和,属于上述第二类题目,可以使用动态规划
- 题目“最小路径和”与此题解法类似
- 来自官方题解的一句话
代码
class Solution {
public:
// void dfs(int x, int y, vector<vector<int>>& obstacleGrid, int& ret){
// int m = obstacleGrid.size();
// int n = obstacleGrid[0].size();
// if(x == m-1 && y == n-1 && obstacleGrid[x][y]==0){
// ret++;
// return;
// }
// vector<vector<int>> updata = {{1,0}, {0, 1}};
// for(int i = 0; i < 2; i++){
// if(x+updata[i][0] < m && y+updata[i][1] < n && obstacleGrid[x+updata[i][0]][y+updata[i][1]] == 0){
// dfs(x+updata[i][0], y+updata[i][1], obstacleGrid, ret);
// }
// }
// }
// int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
// if(obstacleGrid[0][0] == 1){
// return 0;
// }
// int ret=0;
// dfs(0,0,obstacleGrid,ret);
// return ret;
// }
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid){
if(obstacleGrid[0][0] == 1){
return 0;
}
vector<int> num_u(obstacleGrid[0].size(), 0);
num_u[0] = 1;
int m = obstacleGrid.size();
int n = obstacleGrid[0].size();
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
if(i==0&&j==0){
continue;
}
// int num = 0;
// if(obstacleGrid[i][j] == 0){
// if(i-1 >= 0){
// num += num_u[j];
// }
// if(j-1 >= 0){
// num += num_u[j-1];
// }
// }
// num_u[j] = num;
if(obstacleGrid[i][j] == 0){
if(j-1 >= 0){
num_u[j] += num_u[j-1];
}
}
else{
num_u[j] = 0;
}
}
}
return num_u[n-1];
}
};