comments | difficulty | edit_url | tags | |||
---|---|---|---|---|---|---|
true |
中等 |
|
一个机器人位于一个 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
提示:
m == obstacleGrid.length
n == obstacleGrid[i].length
1 <= m, n <= 100
obstacleGrid[i][j]
为0
或1
我们设计一个函数
函数
- 如果
$i \ge m$ 或者$j \ge n$ ,或者$obstacleGrid[i][j] = 1$ ,则路径数为$0$ ; - 如果
$i = m - 1$ 且$j = n - 1$ ,则路径数为$1$ ; - 否则,路径数为
$dfs(i + 1, j) + dfs(i, j + 1)$ 。
为了避免重复计算,我们可以使用记忆化搜索的方法。
时间复杂度
class Solution:
def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int:
@cache
def dfs(i: int, j: int) -> int:
if i >= m or j >= n or obstacleGrid[i][j]:
return 0
if i == m - 1 and j == n - 1:
return 1
return dfs(i + 1, j) + dfs(i, j + 1)
m, n = len(obstacleGrid), len(obstacleGrid[0])
return dfs(0, 0)
class Solution {
private Integer[][] f;
private int[][] obstacleGrid;
private int m;
private int n;
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
m = obstacleGrid.length;
n = obstacleGrid[0].length;
this.obstacleGrid = obstacleGrid;
f = new Integer[m][n];
return dfs(0, 0);
}
private int dfs(int i, int j) {
if (i >= m || j >= n || obstacleGrid[i][j] == 1) {
return 0;
}
if (i == m - 1 && j == n - 1) {
return 1;
}
if (f[i][j] == null) {
f[i][j] = dfs(i + 1, j) + dfs(i, j + 1);
}
return f[i][j];
}
}
class Solution {
public:
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
int m = obstacleGrid.size(), n = obstacleGrid[0].size();
int f[m][n];
memset(f, -1, sizeof(f));
function<int(int, int)> dfs = [&](int i, int j) {
if (i >= m || j >= n || obstacleGrid[i][j]) {
return 0;
}
if (i == m - 1 && j == n - 1) {
return 1;
}
if (f[i][j] == -1) {
f[i][j] = dfs(i + 1, j) + dfs(i, j + 1);
}
return f[i][j];
};
return dfs(0, 0);
}
};
func uniquePathsWithObstacles(obstacleGrid [][]int) int {
m, n := len(obstacleGrid), len(obstacleGrid[0])
f := make([][]int, m)
for i := range f {
f[i] = make([]int, n)
for j := range f[i] {
f[i][j] = -1
}
}
var dfs func(i, j int) int
dfs = func(i, j int) int {
if i >= m || j >= n || obstacleGrid[i][j] == 1 {
return 0
}
if i == m-1 && j == n-1 {
return 1
}
if f[i][j] == -1 {
f[i][j] = dfs(i+1, j) + dfs(i, j+1)
}
return f[i][j]
}
return dfs(0, 0)
}
function uniquePathsWithObstacles(obstacleGrid: number[][]): number {
const m = obstacleGrid.length;
const n = obstacleGrid[0].length;
const f: number[][] = Array.from({ length: m }, () => Array(n).fill(-1));
const dfs = (i: number, j: number): number => {
if (i >= m || j >= n || obstacleGrid[i][j] === 1) {
return 0;
}
if (i === m - 1 && j === n - 1) {
return 1;
}
if (f[i][j] === -1) {
f[i][j] = dfs(i + 1, j) + dfs(i, j + 1);
}
return f[i][j];
};
return dfs(0, 0);
}
我们定义
首先初始化
- 若
$obstacleGrid[i][j] = 1$ ,说明路径数为$0$ ,那么$f[i][j] = 0$ ; - 若
$obstacleGrid[i][j] = 0$ ,则$f[i][j] = f[i - 1][j] + f[i][j - 1]$ 。
最后返回
时间复杂度
class Solution:
def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int:
m, n = len(obstacleGrid), len(obstacleGrid[0])
f = [[0] * n for _ in range(m)]
for i in range(m):
if obstacleGrid[i][0] == 1:
break
f[i][0] = 1
for j in range(n):
if obstacleGrid[0][j] == 1:
break
f[0][j] = 1
for i in range(1, m):
for j in range(1, n):
if obstacleGrid[i][j] == 0:
f[i][j] = f[i - 1][j] + f[i][j - 1]
return f[-1][-1]
class Solution {
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
int m = obstacleGrid.length, n = obstacleGrid[0].length;
int[][] f = new int[m][n];
for (int i = 0; i < m && obstacleGrid[i][0] == 0; ++i) {
f[i][0] = 1;
}
for (int j = 0; j < n && obstacleGrid[0][j] == 0; ++j) {
f[0][j] = 1;
}
for (int i = 1; i < m; ++i) {
for (int j = 1; j < n; ++j) {
if (obstacleGrid[i][j] == 0) {
f[i][j] = f[i - 1][j] + f[i][j - 1];
}
}
}
return f[m - 1][n - 1];
}
}
class Solution {
public:
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
int m = obstacleGrid.size(), n = obstacleGrid[0].size();
vector<vector<int>> f(m, vector<int>(n));
for (int i = 0; i < m && obstacleGrid[i][0] == 0; ++i) {
f[i][0] = 1;
}
for (int j = 0; j < n && obstacleGrid[0][j] == 0; ++j) {
f[0][j] = 1;
}
for (int i = 1; i < m; ++i) {
for (int j = 1; j < n; ++j) {
if (obstacleGrid[i][j] == 0) {
f[i][j] = f[i - 1][j] + f[i][j - 1];
}
}
}
return f[m - 1][n - 1];
}
};
func uniquePathsWithObstacles(obstacleGrid [][]int) int {
m, n := len(obstacleGrid), len(obstacleGrid[0])
f := make([][]int, m)
for i := 0; i < m; i++ {
f[i] = make([]int, n)
}
for i := 0; i < m && obstacleGrid[i][0] == 0; i++ {
f[i][0] = 1
}
for j := 0; j < n && obstacleGrid[0][j] == 0; j++ {
f[0][j] = 1
}
for i := 1; i < m; i++ {
for j := 1; j < n; j++ {
if obstacleGrid[i][j] == 0 {
f[i][j] = f[i-1][j] + f[i][j-1]
}
}
}
return f[m-1][n-1]
}
function uniquePathsWithObstacles(obstacleGrid: number[][]): number {
const m = obstacleGrid.length;
const n = obstacleGrid[0].length;
const f = Array.from({ length: m }, () => Array(n).fill(0));
for (let i = 0; i < m; i++) {
if (obstacleGrid[i][0] === 1) {
break;
}
f[i][0] = 1;
}
for (let i = 0; i < n; i++) {
if (obstacleGrid[0][i] === 1) {
break;
}
f[0][i] = 1;
}
for (let i = 1; i < m; i++) {
for (let j = 1; j < n; j++) {
if (obstacleGrid[i][j] === 1) {
continue;
}
f[i][j] = f[i - 1][j] + f[i][j - 1];
}
}
return f[m - 1][n - 1];
}
function uniquePathsWithObstacles(obstacleGrid: number[][]): number {
const m = obstacleGrid.length;
const n = obstacleGrid[0].length;
const f: number[][] = Array.from({ length: m }, () => Array(n).fill(-1));
const dfs = (i: number, j: number): number => {
if (i >= m || j >= n || obstacleGrid[i][j] === 1) {
return 0;
}
if (i === m - 1 && j === n - 1) {
return 1;
}
if (f[i][j] === -1) {
f[i][j] = dfs(i + 1, j) + dfs(i, j + 1);
}
return f[i][j];
};
return dfs(0, 0);
}
impl Solution {
pub fn unique_paths_with_obstacles(obstacle_grid: Vec<Vec<i32>>) -> i32 {
let m = obstacle_grid.len();
let n = obstacle_grid[0].len();
let mut f = vec![vec![0; n]; m];
for i in 0..n {
if obstacle_grid[0][i] == 1 {
break;
}
f[0][i] = 1;
}
for i in 0..m {
if obstacle_grid[i][0] == 1 {
break;
}
f[i][0] = 1;
}
for i in 1..m {
for j in 1..n {
if obstacle_grid[i][j] == 1 {
continue;
}
f[i][j] = f[i - 1][j] + f[i][j - 1];
}
}
f[m - 1][n - 1]
}
}