📌  相关文章
📜  门| Sudo GATE 2020 Mock I(2019年12月27日)|问题2(1)

📅  最后修改于: 2023-12-03 14:58:33.124000             🧑  作者: Mango

门 | Sudo GATE 2020 Mock I(2019年12月27日)|问题2

题目描述

给定一个二维数组,其中非负整数表示每个点的高度。从网格左上角开始,每一步可以向右或向下移动。求到达网格右下角的最小路径和。

示例

输入:[[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)$,需要维护一个大小与原矩阵相同的的最小路径和矩阵。