力扣题目
解题思路
java代码
力扣题目:
给定一个 m x n
的整数数组 grid
。一个机器人初始位于 左上角(即 grid[0][0]
)。机器人尝试移动到 右下角(即 grid[m - 1][n - 1]
)。机器人每次只能向下或者向右移动一步。
网格中的障碍物和空位置分别用 1
和 0
来表示。机器人的移动路径中不能包含 任何 有障碍物的方格。
返回机器人能够到达右下角的不同路径数量。
测试用例保证答案小于等于 2 * 109
。
示例 1:
输入:obstacleGrid = [[0,0,0],[0,1,0],[0,0,0]]
输出:2
解释:3x3 网格的正中间有一个障碍物。
从左上角到右下角一共有 2
条不同的路径:
1. 向右 -> 向右 -> 向下 -> 向下
2. 向下 -> 向下 -> 向右 -> 向右
示例 2:
输入:obstacleGrid = [[0,1],[0,0]] 输出:1
解题思路:
算法原理:
这道题使用动态规划来计算在有障碍物的网格中从左上角到右下角的不同路径数量。
思路:
- 首先创建一个二维
dp
数组来保存中间计算结果。 - 初始化第一行和第一列,如果遇到障碍物则停止初始化(将后续位置都设为 0 )。
- 对于其他位置,如果没有障碍物,其路径数量等于上方位置和左侧位置的路径数量之和。
- 最终返回右下角位置的路径数量。
代码分析:
- 前两个嵌套的循环分别初始化第一行和第一列的
dp
值。 - 第三个嵌套的循环根据状态转移方程计算其他位置的
dp
值。
时间复杂度:O(mn),其中 m
是网格的行数,n
是网格的列数,需要遍历整个网格。
空间复杂度:O(mn),用于存储 dp
数组。
java代码:
package com.example.lib;
public class Leetcode63 {
public static void main(String[] args) {
int[][] obstacleGrid = new int[][]{
{0,0,0},
{0,1,0},
{0,0,0}
};
System.out.println(uniquePathsWithObstacles(obstacleGrid));
}
public static int uniquePathsWithObstacles(int[][] obstacleGrid) {
int m = obstacleGrid.length;
int n = obstacleGrid[0].length;
int[][] dp = new int[m][n];
for (int i = 0; i < m; i++) {
if (obstacleGrid[i][0] == 1) break;
dp[i][0] = 1;
}
for (int i = 0; i < n; i++) {
if (obstacleGrid[0][i] == 1) break;
dp[0][i] = 1;
}
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
if (obstacleGrid[i][j] == 1) continue;
dp[i][j] = dp[i-1][j] + dp[i][j-1];
}
}
return dp[m-1][n-1];
}
}
更多详细内容同步到公众号,感谢大家的支持!
每天都会给刷算法的小伙伴推送明日一题,并且没有任何收费项