📅  最后修改于: 2023-12-03 15:36:16.745000             🧑  作者: Mango
考虑给定一个矩阵 m
,矩阵大小为 MxN
,现在有一个机器人从矩阵的左上角 (0,0) 的位置开始移动。机器人每次可以向右或向下移动一步,直到到达矩阵的右下角 (M-1,N-1)
的位置。请问,从左上角出发,到达 (M-1,N-1)
的位置有多少种不同的走法?
除了上述情况,现在我们给出一个坐标 (X,Y)
, 机器人不能通过该坐标前往。
例如,对于一个 3x3
的矩阵,其中 (1,1)
的位置不能走。那么从原点到 (2,2)
的走法数量为 2
, 从原点到 (2,0)
的走法数量为 3
。
这是一道经典的动态规划问题。我们定义状态 dp(i,j)
为到达矩阵的 (i,j)
点的方案数。则有递推方程式:
当 (i,j)
是挡板时,dp(i,j) = 0
。
否则,有 dp(i, j) = dp(i-1, j) + dp(i, j-1)
。
初始状态为 dp(0,0) = 1
。
最终答案即为 dp(M-1, N-1)
。
def uniquePaths(m: int, n: int, obstacle: List[List[int]]) -> int:
dp = [[0] * n for _ in range(m)]
dp[0][0] = 1
for i in range(m):
for j in range(n):
if i == 0 and j == 0:
continue
if obstacle[i][j] == 1:
continue
if i == 0:
dp[i][j] = dp[i][j-1]
elif j == 0:
dp[i][j] = dp[i-1][j]
else:
dp[i][j] = dp[i-1][j] + dp[i][j-1]
return dp[m-1][n-1]
这里的 obstacle
是一个大小为 MxN
的二维数组,表示每个位置是否有障碍物。其中值为 1
表示当前位置为障碍,值为 0
表示当前位置没有障碍。
该算法时间复杂度为 O(MN)
,空间复杂度为 O(MN)
。
除了上述解法,还有一种更为简单的解法,即组合数学,就是从左上角到右下角,需要向右移动 N-1
次,并向下移动 M-1
次。因此,总共需要走 M+N-2
步。这其中需要挑选 N-1
步向右走,或者挑选 M-1
步向下走。因此,答案即为组合数 $\binom{M+N-2}{N-1}$。
注意到,以上解法中,我们没有考虑到障碍物的信息。如果要考虑障碍物,只需要在计算组合数时,不考虑经过障碍物的路径即可。
def uniquePaths(m: int, n: int, obstacle: List[List[int]]) -> int:
total = m + n - 2
right = n - 1
res = 1
for i in range(total, total-right, -1):
res *= i
for i in range(1, right+1):
res //= i
return res