leetcode动态规划(六)-不同路径(有障碍物)
题目
63.不同路径(有障碍物)
给定一个 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
提示:
m == obstacleGrid.length
n == obstacleGrid[i].length
1 <= m, n <= 100
obstacleGrid[i][j]
为0
或1
思路
1.确定dp数组(dp table)以及下标的含义
dp[i][j]表示从坐标[0][0]到坐标[i][j]一共有多少种路径
2.确定递推公式
和无障碍物路径一样,dp[i][j]依赖dp[i-1][j]和dp[i][j-1]
3.dp数组如何初始化
题目已经给了障碍物的情况,在初始化第一行和第一列的时候,需要注意在有障碍物的后面的位置均是无路径的,都需要设置为0,而当obstacleGrid[i][j]中显示为0的时候,就是这里可以通过,那就赋值为1即可
4.确定遍历顺序
由递推公式可知,是需要从前往后来进行遍历的
5.举例推导dp数组
代码
class Solution:
def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int:
if obstacleGrid[0][0]==1 or obstacleGrid[-1][-1]==1:
return 0
m = len(obstacleGrid)
n = len(obstacleGrid[0])
dp = [[0]*n for _ in range(m)]
for i in range(m):
if obstacleGrid[i][0]==0:
dp[i][0] = 1
if obstacleGrid[i][0]==1:
break
for j in range(n):
if obstacleGrid[0][j] == 0:
dp[0][j] = 1
if obstacleGrid[0][j] == 1:
break
for i in range(1,m):
for j in range(1,n):
if obstacleGrid[i][j] == 1:
dp[i][j] = 0
else:
dp[i][j] = dp[i-1][j]+dp[i][j-1]
return dp[-1][-1]