📅  最后修改于: 2023-12-03 14:58:33.124000             🧑  作者: Mango
给定一个二维数组,其中非负整数表示每个点的高度。从网格左上角开始,每一步可以向右或向下移动。求到达网格右下角的最小路径和。
输入:[[1,3,1],[1,5,1],[4,2,1]]
输出:7
解释:左上角的点为1,即最小路径为1+3+1+1+1=7。
该问题可以使用动态规划求解。首先,我们需要明确每次只能向右或向下移动,因此对于每个点,它只会从上方或左侧的点走过来。因此,我们可以通过递推来得到最小路径和。
具体而言,对于矩阵中的每个点,我们可以记录到达该点的最小路径和。那么,对于最上侧和最左侧的点,它们只能从起点出发向右/向下移动到达,因此它们到达的路径和即为数组中对应数值的和。对于其他位置的点,它们既可以从上方移动下来,也可以从左侧移动过来,因此它们可以由上方或左侧的点递推而来。具体而言,假设当前矩阵位置为$(i,j)$,则可以递推得到:
$$dp(i,j) = \min{dp(i-1,j),dp(i,j-1)} + grid(i,j)$$
其中 $dp(i,j)$ 表示到达矩阵位置$(i,j)$的最小路径和,可以由其上方位置 $(i-1,j)$ 和左侧位置 $(i,j-1)$ 的最小路径和递推而来,两者取较小值再加上该点的值即为 $dp(i,j) $ 的值。
最后,到达矩阵右下角的最小路径和即为 $dp(m-1,n-1)$。其中 $(m,n)$ 分别为矩阵的长和宽。
def minPathSum(grid):
m, n = len(grid), len(grid[0])
# 初始化最小路径和矩阵
dp = [[0] * n for _ in range(m)]
# 对于左上角的矩阵位置,到达其的最小路径和即为该位置的值
dp[0][0] = grid[0][0]
# 初始化最上侧和最左侧的路径和
for i in range(1, m):
dp[i][0] = dp[i-1][0] + grid[i][0]
for j in range(1, n):
dp[0][j] = dp[0][j-1] + grid[0][j]
# 递推得出每个位置的最小路径和
for i in range(1, m):
for j in range(1, n):
dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j]
# 返回最后一个位置的最小路径和
return dp[-1][-1]
时间复杂度:$O(mn)$,其中 $m$ 和 $n$ 分别为矩阵的长和宽。
空间复杂度:$O(mn)$,需要维护一个大小与原矩阵相同的的最小路径和矩阵。