一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish”)。
现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?
网格中的障碍物和空位置分别用 1 和 0 来表示。
示例 1:
输入:obstacleGrid = [[0,0,0],[0,1,0],[0,0,0]]
输出:2
解释:3x3 网格的正中间有一个障碍物。
从左上角到右下角一共有 2 条不同的路径:
- 向右 -> 向右 -> 向下 -> 向下向下 -> 向下 -> 向右 -> 向右
示例 2:
输入:obstacleGrid = [[0,1],[0,0]]
输出:1
提示:
m == obstacleGrid.length,(c++)为size()
n == obstacleGrid[i].length,(c++)为size()
1 <= m, n <= 100
obstacleGrid[i][j] 为 0 或 1
思路:
很显然,这道题可以使用动态规划来做.我们先确认动态规划的状态转移方程,因为每次只能往右边或者下面移动,所以每次都有两种移动的方案,而这样就可以得出每一个位置处的前一步必定为上方或者左方,也就可以得出路线数为上方位置的路线数加上左方的路线数.这样也就列出了状态转移方程了,即res[i][j]=res[i -1][j] + res[i][j - 1],当此处没有障碍物时.有障碍物就res等于0;
然后我们再分析一下初始条件,动动脑子可得,第一行和第一列上的不管哪个位置都是有且只有一条路线的,一路畅通就res都赋值为1,有障碍物就从障碍物开始以后的res为0,因为路被挡死了.
然后就可以通过循环来把对应的结果得出了.
要记得初始化为0,要不然遇到一些一开始就给你障碍物的就寄了.
如果要用vector的话就可以这样创建二维动态数组,都初始化为0
vector> res(n, vector (m, 0));
当然可以简单地使用数组,用memset来进行初始化
int res[n][m]; memset(res, 0, sizeof(res));
代码区:
class Solution {
public:
int uniquePathsWithObstacles(vector>& obstacleGrid) {
int n = obstacleGrid.size();//行数
int m = obstacleGrid[0].size();//列数
vector> res(n, vector(m, 0));//建立n行m列初始化为0的动态二维数组
for(int i = 0; i < n && obstacleGrid[i][0] != 1; i++){
//加一个条件就可以实现当遇到1时停止赋值,因为已经过不去了,死路默认值为0
res[i][0] = 1;
}
for(int j = 0; j < m && obstacleGrid[0][j] != 1; j++){
//同上
res[0][j] = 1;
}
for(int i = 1; i < n; i++){//从非第一行列开始进行判断,
for(int j = 1; j < m; j++){
if(obstacleGrid[i][j] == 0){//只有通路时进行路线的相加,即上方和左方的路线相加
res[i][j] = res[i - 1][j] + res[i][j - 1];
}
//因为已经初始化过了,所以不用考虑有障碍物,默认为0
}
}
//返回最终的结果
return res[n - 1][m - 1];
}
};
新手上路,有错请指正;



