与LeetCode第 62 题:不同路径(C++)_zj-优快云博客的区别在于障碍物,障碍物不能通过。
不过其他思路还是类似的,只不过走到每一个方格之前,需要判断方格是否是空格,然后对路径做出相应调整:
二维数组的思路:
class Solution {
public:
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
int m = obstacleGrid.size(), n = obstacleGrid[0].size();//实测输入不会为空
if(obstacleGrid[0][0] == 1 || obstacleGrid[m-1][n-1] == 1) return 0;//路径起点/终点不可达
vector<vector<int>> f(m, vector<int>(n, 0));//初始化为0(这儿初始化为0方便了下面的计算)
for(int i = 0; i < m; ++i){
for(int j = 0; j < n; ++j){
if(i == 0 && j == 0) f[0][0] = 1;//左上角
else if(i == 0){//第一行
if(obstacleGrid[i][j] == 0) f[i][j] = 1;//可达
else break;//某个点有障碍,则第一行该方格之后的所有位置均不可达(默认设置为0)
}
else if(j == 0){//第一列
if(obstacleGrid[i][j] == 0) f[i][j] = f[i-1][j];只要进入else,就会有一个点被设为0,那么之后的每次循环都会得到0,这也是我们想要的
else continue; //不可达,之后每次到这儿的时候也会把障碍之后的所有点设为不可达的
}else{
if(obstacleGrid[i][j] == 0) f[i][j] = f[i][j-1] + f[i-1][j];
else f[i][j] = 0;
}
}
}
return f[m-1][n-1];
}
};
换种写法优化一下:
class Solution {
public:
int dp[110][110];
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
int m = obstacleGrid.size(), n = obstacleGrid[0].size();
if(obstacleGrid[0][0] == 1 || obstacleGrid[m-1][n-1] == 1) return 0;
for(int i = 1; i <= m; ++i){
for(int j = 1; j <= n; ++j){
if(i == 1 && j == 1) dp[i][j] = 1;
else if(obstacleGrid[i-1][j-1] == 0) dp[i][j] = dp[i-1][j] + dp[i][j-1];
}
}
return dp[m][n];
}
};
下面还是老规矩了,可以进行空间优化吗?应该也是可以的,直接使用一维数组进行优化,思路也是和上一题类似
class Solution {
public:
int dp[110];
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
int m = obstacleGrid.size(), n = obstacleGrid[0].size();
if(obstacleGrid[0][0] == 1 || obstacleGrid[m-1][n-1] == 1) return 0;
dp[1] = 1;
for(int i = 1; i <= m; ++i){
for(int j = 1; j <= n; ++j){
if(obstacleGrid[i-1][j-1] == 0) dp[j] += dp[j-1];
else dp[j] = 0;
}
}
return dp[n];
}
};