LeetCode算法系列(Java版) 62. 不同路径
LeetCode算法系列(Java版) 63. 不同路径 II
力扣原题
63. 不同路径 II
一个机器人位于一个 m x n
网格的左上角 (起始点在下图中标记为“Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。
现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?
网格中的障碍物和空位置分别用 1 和 0 来表示。
示例 1:
输入:obstacleGrid = [[0,0,0],[0,1,0],[0,0,0]]
输出:2
解释:
3x3 网格的正中间有一个障碍物。
从左上角到右下角一共有 2 条不同的路径:
1. 向右 -> 向右 -> 向下 -> 向下
2. 向下 -> 向下 -> 向右 -> 向右
示例 2:
输入:obstacleGrid = [[0,1],[0,0]]
输出:1
解题思路
根据上一篇 LeetCode算法系列 62. 不同路径,我们知道使用动态规划来解决这个问题。
我们用 表示从左上角走到 的路径数量,其中 和 的范围分别是 和 。
由于我们每一步只能从向下或者向右移动一步,因此要想走到 ,如果向下走一步,那么会从 走过来;如果向右走一步,那么会从 走过来。因此我们可以写出动态规划转移方程:
那我们现在引入障碍物,该怎么办呢?
我们用 来表示从坐标 到坐标 的路径总数, 表示坐标 是否可行,如果坐标 有障碍物,,否则 。假如存在障碍物,,相当于我这条路径废了, 并不能从 和 到达,而 。综上所述,我们可以得到这样的动态规划转移方程:
代码实现
class Solution {
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
// 定义 dp 数组并初始化第 1 行和第 1 列。
int m = obstacleGrid.length, n = obstacleGrid[0].length;
int[][] dp = new int[m][n];
for (int i = 0; i < m && obstacleGrid[i][0] == 0; i++) {
dp[i][0] = 1;
}
for (int j = 0; j < n && obstacleGrid[0][j] == 0; j++) {
dp[0][j] = 1;
}
// 根据状态转移方程 dp[i][j] = dp[i - 1][j] + dp[i][j - 1] 进行递推。
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
if (obstacleGrid[i][j] == 0) {
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
}
}
}
return dp[m - 1][n - 1];
}
}
复杂度分析
-
时间复杂度:。
-
空间复杂度:,即为存储所有状态需要的空间。注意到 仅与第 行和第 行的状态有关,因此我们可以使用滚动数组代替代码中的二维数组,使空间复杂度降低为 。此外,由于我们交换行列的值并不会对答案产生影响,因此我们总可以通过交换 和 使得 ,这样空间复杂度降低至 。
LeetCode算法系列(Java版) 62. 不同路径
LeetCode算法系列(Java版) 63. 不同路径 II
原文始发于微信公众号(白菜说技术):LeetCode算法系列(Java版) 63. 不同路径 II
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/172788.html