这里,我们将遇到两类不同路径的问题,第一类不考虑障碍物,第二类考虑障碍物。
1. 不考虑障碍物
问题来源:不同路径I
问题描述:一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。
问总共有多少条不同的路径?
示例:
输入: m = 3, n = 2
输出: 3
解释:
从左上角开始,总共有 3 条路径可以到达右下角。
- 向右 -> 向右 -> 向下
- 向右 -> 向下 -> 向右
- 向下 -> 向右 -> 向右
class Solution:
def uniquePaths(self, m: int, n: int) -> int:
# 记d(i, j)为(i+1)X(j+1)网格中总路径数
# d(i, j) = d(i-1, j) + d(i, j-1)
# d(0, j) = 1; d(i, 0) = 1
# 构建二维矩阵d(i, j)
d = [[0 for j in range(n)] for i in range(m)]
# 动态规划
for i in range(m):
for j in range(n):
# 边界条件
if i == 0 or j == 0: d[i][j] = 1
# 转移方程
else:
d[i][j] = d[i-1][j] + d[i][j-1]
# 返回值
return d[m-1][n-1]
2. 考虑障碍物
问题来源:不同路径II
问题描述:一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。
现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?
网格中的障碍物和空位置分别用 1 和 0 来表示。
示例:
输入:
[
[0,0,0],
[0,1,0],
[0,0,0]
]
输出: 2
解释:
3x3 网格的正中间有一个障碍物。
从左上角到右下角一共有 2 条不同的路径:
- 向右 -> 向右 -> 向下 -> 向下
- 向下 -> 向下 -> 向右 -> 向右
class Solution:
def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int:
# 如果开始位置为障碍物,则无路径
if obstacleGrid[0][0] == 1: return 0
# 如果目标位置为障碍物,则无路径
if obstacleGrid[-1][-1] == 1: return 0
# 定义状态:d(m-1, n-1)为m*n网格的路径总数
# 状态转移:
# 如果左边和上边都是障碍物,则d(i, j) = 0
# 如果左边是障碍物,则d(i, j) = d(i-1, j)
# 如果上边是障碍物,则d(i, j) = d(i, j-1)
# 如果左边和上边都没有障碍物,则d(i, j) = d(i-1, j) + d(i, j-1)
# 边界条件:
# 如果i=0,若左边是障碍物,则d(i, j) = 0;若左边没有障碍物,则d(i, j)=d(i, j-1)
# 如果j=0,若上边有障碍物,则d(i, j) = 0; 若上边没有障碍物,则d(i, j)=d(i-1, j)
m = len(obstacleGrid) # 行数
n = len(obstacleGrid[0]) # 列数
# 定义二维矩阵
d = [[-1 for j in range(n)] for i in range(m)]
for i in range(m):
for j in range(n):
# 边界条件
## 起始点默认为1条路径到达
if i == 0 and j == 0:
d[i][j] = 1
## 如果在第一行
elif i == 0:
if obstacleGrid[i][j-1] == 1:
d[i][j] = 0
else:
d[i][j] = d[i][j-1]
## 如果在第一列
elif j == 0:
if obstacleGrid[i-1][j] == 1:
d[i][j] = 0
else:
d[i][j] = d[i-1][j]
# 状态转移
else:
## 如果上边和左边都是障碍物
if obstacleGrid[i-1][j] == 1 and obstacleGrid[i][j-1] == 1:
d[i][j] = 0
## 如果只有上边是障碍物
elif obstacleGrid[i-1][j] == 1:
d[i][j] = d[i][j-1]
## 如果只有左边是障碍物
elif obstacleGrid[i][j-1] == 1:
d[i][j] = d[i-1][j]
## 如果左边和上边都没有障碍物
else:
d[i][j] = d[i][j-1] + d[i-1][j]
return d[m-1][n-1]