该题是 Leetcode 62. 不同路径 https://blog.csdn.net/qq_38742161/article/details/90814802 的增强版本,需要将62掌握后再分析该题。
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。
现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?
网格中的障碍物和空位置分别用
1
和0
来表示。说明:m 和 n 的值均不超过 100。
示例 1:
输入: [ [0,0,0], [0,1,0], [0,0,0] ] 输出: 2 解释: 3x3 网格的正中间有一个障碍物。 从左上角到右下角一共有2
条不同的路径: 1. 向右 -> 向右 -> 向下 -> 向下 2. 向下 -> 向下 -> 向右 -> 向右
tips:62中,我们采用动态规划/统计学进行分析,在该题中因为障碍物的加入,统计学思想难度较大。我们仍然沿用动态规划进行, 无障碍中动态规划的状态转移方程为 f(m,n)=f(m-1,n)+f(m,n-1)。 那么添加障碍物后,达到障碍处的路径为0,那么我们将转移方程中f(x,y)置0即可。为了不与路径条数混淆,将输入数组中1替换为-1.完整代码如下:
class Solution:
def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int:
m,n=len(obstacleGrid),len(obstacleGrid[0])
if m==1 or n==1:
maxi= max(max(i) for i in obstacleGrid)
if maxi==1:
return 0
return 1
def dp(arr,m,n):
#将输入数组中1替换为-1
for i in range(m):
for j in range(n):
if arr[i][j]==1:
arr[i][j]=-1
#边界判断,方格左边界
flag=0
for i in range(m):
if arr[i][0]!=0:
flag=1
if flag==1:
arr[i][0]=-1
else:
arr[i][0]=1
#边界判断,方格上边界
flag=0
for i in range(n):
if arr[0][i]==-1:
flag=1
if flag==1:
arr[0][i]=-1
else:
arr[0][i]=1
#动态规划转移方程
for i in range(1,m):
for j in range(1,n):
if arr[i][j]!=-1:
if arr[i-1][j]!=-1:
arr[i][j]+=arr[i-1][j]
if arr[i][j-1]!=-1:
arr[i][j]+=arr[i][j-1]
return arr[-1][-1] if arr[-1][-1] !=-1 else 0
return dp(obstacleGrid,m,n)