问题描述:
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。
现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?
网格中的障碍物和空位置分别用 1
和 0
来表示。
说明:m 和 n 的值均不超过 100。
示例 1:
输入:
[
[0,0,0],
[0,1,0],
[0,0,0]
]
输出: 2
解释:
3x3 网格的正中间有一个障碍物。
从左上角到右下角一共有 2 条不同的路径:
1. 向右 -> 向右 -> 向下 -> 向下
2. 向下 -> 向下 -> 向右 -> 向右
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/unique-paths-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
执行结果:
代码描述:
思路:当遇到障碍物时,此位置直接赋值为 0, 不再累加,因为但凡通过该位置的方法,都不可行。
第一行和第一列需要特殊处理,如果第一行和第一列没有障碍物,可以直接赋值为 1,也就是把左边一个(行)或上一个(列)直接拿下来。但是一旦遇到第一行或者第一列有障碍物时,把左边一个(行)或上一个(列)拿下来时,就是0。
时间复杂度O(n*m),空间复杂度O(n*m)
class Solution {
public:
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
if(obstacleGrid.size() == 0 || obstacleGrid[0].size() == 0) return 0;//判断数组的合理性
int m = obstacleGrid.size();
int n = obstacleGrid[0].size();
long long dp[m][n]; // 数据中有极大数,需要注意
for(int i = 0; i < m; ++i)
{
for(int j = 0; j < n; ++j)
{
if(obstacleGrid[i][j] == 1) //如果有障碍物,则说明但凡通过此位置的,都不通,所以设置为0
{
dp[i][j] = 0;
}
else
{
if(i == 0 && j == 0) // 起点为1
dp[i][j] = 1;
else
{
dp[i][j] = 0; // 一定需要把位置先初始化为0
if(i >= 1) dp[i][j] += dp[i-1][j]; //由于存在障碍物,所以第一行和第一列不能直接赋值为 1
if(j >= 1) dp[i][j] += dp[i][j-1];
}
}
}
}
return dp[m-1][n-1];
}
};
方案二,当传入的数组可以被改变时,那就可以原地进行计算,此时空间复杂度为O(1)。但是,由于测试数据中,有极大数,obstacleGrid 内存储的为int型,内存溢出。