题目:63. 不同路径 II
思路
动态规划
需要考虑障碍物,不仅仅是障碍物所在的地方不能到达,而且会阻碍后面的;
假设f[i][j]
有障碍物,那么就令f[i][j] = 0
,在状态转移方程中f[i][j] = f[i-1][j] + f[i][j-1];
如果前一个是有障碍物的,那么自然为0
,式子不需要专门改变;
(下面我写的方法显然是现场第一遍写,边写边调试改出来的样子)
代码
我写的
// f[i][j] : 从起点到[i][j]有多少种路径
// f[i][j] = f[i-1][j] + f[i][j-1], 如果来的路上有障碍物, +0不影响结果
// 最左边一列,最上边一行为 1, 有障碍物为 0;
// i: 0->m-1, j: 0->n-1
//
class Solution {
public:
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
int i, j;
int m = obstacleGrid.size(), n = obstacleGrid[0].size();
vector<vector<int>> f(m, vector<int>(n, 0));
for(i = 0; i < m; i++)
{
if(obstacleGrid[i][0] == 1 || (i > 0 && obstacleGrid[i-1][0] == 1) || (i > 0 && f[i-1][0] == 0))
{
f[i][0] = 0;
}
else
{
f[i][0] = 1;
}
}
for(j = 0; j < n; j++)
{
if(obstacleGrid[0][j] == 1 || (j > 0 && obstacleGrid[0][j-1] == 1) || (j > 0 && f[0][j-1] == 0))
{
f[0][j] = 0;
}
else
{
f[0][j] = 1;
}
}
for(i = 0; i < m; i++)
{
for(j = 0; j < n; j++)
{
cout << f[i][j];
}
cout << endl;
}
cout << endl;
for(i = 1; i < m; i++)
{
for(j = 1; j < n; j++)
{
if(obstacleGrid[i-1][j] == 1)
{
f[i-1][j] = 0;
}
if(obstacleGrid[i][j-1] == 1)
{
f[i][j-1] = 0;
}
if(obstacleGrid[i][j] == 1)
{
f[i][j] = 0;
}
else
{
f[i][j] = f[i-1][j] + f[i][j-1];
}
}
}
for(i = 0; i < m; i++)
{
for(j = 0; j < n; j++)
{
cout << f[i][j];
}
cout << endl;
}
return f[m-1][n-1];
}
};
代码随想录版本
class Solution {
public:
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
int i, j;
int m = obstacleGrid.size(), n = obstacleGrid[0].size();
vector<vector<int>> f(m, vector<int>(n, 0));
for(i = 0; i < m; i++)
{
if(obstacleGrid[i][0] == 1)
{
break;
}
f[i][0] = 1;
}
for(j = 0; j < n;j++)
{
// 障碍后面的都达不到
if(obstacleGrid[0][j] == 1)
{
break;
}
f[0][j] = 1;
}
for(i = 1; i < m; i++)
{
for(j = 1; j < n;j++)
{
if(obstacleGrid[i][j] == 1)
{
continue;
}
f[i][j] = f[i-1][j] + f[i][j-1];
// 前一个如果是障碍,那么前一个就是0,所以没必要改变状态转移方程
}
}
return f[m-1][n-1];
}
};