1、题目描述:
2、题解:
动态规划,
此题输入填表格的动态规划,与力扣62. 不同路径思路差不多。只不过多了障碍物,也就是障碍物的时候dp设置为0。
定义状态:
dp[i][j]为起始点到(i,j)处的路径数
状态转移方程:
机器人只能向左或者向下,dp[i][j] = dp[i-1][j] + dp[i][j-1]。但是遇到障碍物不更新
算法:
1、如果网格为空,则不存在路径,返回0
如果第一个格点或者结束位置有障碍物,那么机器人不能做任何移动或到达不了结束位置,我们返回结果 0。
定义状态数组dp[m][n],令所有网格初始化为0
否则 ,我们初始化dp[0][0]为 1 然后继续算法。
2、遍历第一列,如果[i,0]没有障碍物,设这个值是前一个节点的值dp[i,0] = dp[i-1,0]。
(其效果是,如果该位置有障碍物,则该位置的下面的位置都到不了)
3、遍历第一行,如果[0,j]没有障碍物,设这个值是前一个节点的值 dp[0,j] = dp[0,j-1]。
(其效果是,如果该位置有障碍物,则该位置的右面的位置都到不了)
4、从 obstacleGrid[1,1] 开始遍历整个数组,如果这个点有障碍物,设值为 0 ,这可以
保证不会对后面的路径产生贡献。如果某个格点初始不包含任何障碍物,就把值赋为上方和左侧两个格点
方案数之和 dp[i,j] = dp[i-1,j] + dp[i,j-1]。
class Solution:
def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int:
#动态规划
if len(obstacleGrid) == 0 or len(obstacleGrid[0]) == 0:
return 0
if obstacleGrid[0][0] == 1 or obstacleGrid[-1][-1] == 1:
return 0
m ,n = len(obstacleGrid),len(obstacleGrid[0])
dp = [[0] * n for _ in range(m)]
dp[0][0] = 1
# 第一列
for i in range(1,m):
if obstacleGrid[i][0] == 0:
dp[i][0] = dp[i - 1][0]
# 第一行
for j in range(1,n):
if obstacleGrid[0][j] == 0:
dp[0][j] = dp[0][j - 1]
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]
时间和空间复杂度都是O(M*N),空间可以继续优化O(1)。我们在所给的obstacleGrid数组上修改就行,思路和上面差不多,代码如下:
class Solution:
def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int:
# 动态规划,不通过
if len(obstacleGrid) == 0 or len(obstacleGrid[0]) == 0:
return 0
if obstacleGrid[0][0] == 1 or obstacleGrid[-1][-1] == 1:
return 0
m, n = len(obstacleGrid), len(obstacleGrid[0])
obstacleGrid[0][0] = 1
# 第一列
for i in range(1, m):
if obstacleGrid[i][0] == 0:
obstacleGrid[i][0] = obstacleGrid[i - 1][0]
else:
obstacleGrid[i][0] = 0
# 第一行
for j in range(1, n):
if obstacleGrid[0][j] == 0:
obstacleGrid[0][j] = obstacleGrid[0][j - 1]
else:
obstacleGrid[0][j] = 0
for i in range(1, m):
for j in range(1, n):
if obstacleGrid[i][j] == 1:
obstacleGrid[i][j] = 0
else:
obstacleGrid[i][j] = obstacleGrid[i - 1][j] + obstacleGrid[i][j - 1]
return obstacleGrid[-1][-1]