一、题目描述
二、题目翻译
还是给定一个网格,在条件A 和 B 的限制下,求出网格起点到终点的路线数量。
条件A:机器人每次只能向下或者向右移动一步。
条件B:网格中增加障碍物,遇到障碍物则不可通过。
备注:网格中的障碍物和空位置分别用 1 和 0 来表示。
输入:二维数组。
三、再来点用例
四、思路讲解
我们可以缩小一下规格,只考虑2*2的网格,如下图:
由上面的图我们可知,从黄球的位置考虑,绿球 -> 黄球 的路径为2条。也就是(1, 0) + (0, 1),但是(0, 1)是障碍物,障碍物是不可通过的,默认是0,所以此时的 绿球 -> 黄球 的公式是下面这样:
绿球到达(1, 0) 的路径数 + 绿球到达(0, 1)的路径数 == 绿球到达(1, 0)的路径数。
根据上面的分析我们可以写出如下代码:
/**
* @param {number[][]} obstacleGrid -> 假设此时是2*2的二维网格
* @return {number}
*/
var uniquePathsWithObstacles = function(obstacleGrid) {
let xLength = obstacleGrid.length; // 有多少个横轴
let yLength = obstacleGrid[0].length; // 有多少个纵轴
let dp = new Array(xLength).fill(new Array(yLength))
for(let x = 0; x < xLength; x++){
for (let y = 0; y < yLength; y++){
if (x > 0 && y > 0){
// dp[x][y]:黄球的位置,dp[x-1][y]:障碍物的位置,dp[x][y-1]:(1, 0) 的位置
dp[x][y] = dp[x-1][y] + dp[x][y-1];
}
}
}
return dp[xLength - 1][yLength - 1];
}
很好,我们现在已经写出来一部分了,但是目前还不能得出来正确的结论,因为我们的二维数组dp里的每一项都没有存储到达这个位置时需要的路径数。
如何存储每个单元格需要的路径数?
- 先判断这个单元格是否是
障碍物, 如果是,则为0,如果不是的话,请往下走 - 如果是第0行上的单元格,那么会有 dp[x][y] = dp[x][y-1]。因为第0行上的单元格,只能通过它左侧的单元格到达
- 如果是第0列上的单元格,那么会有 dp[x][y] = dp[x-1][y]。因为第0列上的单元格,只能通过它上面的单元格到达
- 剩余的单元格,那么会有 dp[x][y] = dp[x-1][y] + dp[x][y-1]。这个说的就是黄球。
根据上面的分析,我们来把剩下的代码补全:
/**
* @param {number[][]} obstacleGrid -> 假设此时是2*2的二维网格
* @return {number}
*/
var uniquePathsWithObstacles = function(obstacleGrid) {
let xLength = obstacleGrid.length; // 有多少个横轴
let yLength = obstacleGrid[0].length; // 有多少个纵轴
let dp = new Array(xLength).fill(new Array(yLength));
// 初始化单元格初始的位置,如果起始位置是障碍物,那就将值置为0,否则就置为1。
// 初始的位置如果不是障碍物,为什么要置为1?
// 其实这是从题意分析出来的,因为第0行上的单元格,如果都不是障碍物,
// 那么到达第0行上的其他单元格的路径数应该是1,
// 第0行上的单元格的规则:dp[x][y] = dp[x][y-1],
// 所以最开始的位置如果不是障碍物,就必须置为1。
dp[0][0] = obstacleGrid[0][0] == 1 ? 0 : 1;
for(let x = 0; x < xLength; x++){
for (let y = 0; y < yLength; y++){
if (obstacleGrid[x][y] == 1){
dp[x][y] == 0;
} else {
if (x > 0 && y > 0){
// dp[x][y]:黄球的位置,dp[x-1][y]:障碍物的位置,dp[x][y-1]:(1, 0) 的位置
dp[x][y] = dp[x-1][y] + dp[x][y-1];
} else if (x == 0 && y > 0){
dp[x][y] = dp[x][y-1];
} else if (y == 0 && x > 0){
dp[x][y] = dp[x-1][y];
}
}
}
}
return dp[xLength - 1][yLength - 1];
}
五、结尾
如果这篇文章能够在思维上帮助你,还请客官不要吝啬手里的小赞赞。我们下篇文章再见喽。