📜  门| GATE CS 2018 |第 39 题(1)

📅  最后修改于: 2023-12-03 15:12:36.462000             🧑  作者: Mango

GATE CS 2018 | 第 39 题

本题考察了程序的时间复杂度和空间复杂度的理解,以及动态规划思想的运用。

题目描述

给定一个m x n的矩阵,每个位置上的数都是正整数,从左上角出发,每次只能向右走或向下走,最后到达右下角。求从左上角走到右下角的所有路径中,路径上的数之和最小的一条路径,并输出它的路径上所有数的值。

示例
Input:
mat[3][3] = {{1, 2, 3},
             {4, 8, 2},
             {1, 5, 3}}
Output: 8
Path : 1 -> 2 -> 3 -> 2 -> 3

Input:
mat[2][3] = {{4, 3, 1},
             {5, 6, 1}}
Output: 12
Path : 4 -> 3 -> 1 -> 1 -> 1
解题思路
  • 利用动态规划思想,从左上角开始遍历矩阵,对于每一个位置,计算到达该位置的所有路径中,路径上的数之和最小的一条路径,并将路径上所有数的和累加到该位置上。
  • 由于每个位置只能从上面或左边的位置到达,因此计算到达某个位置上的最小路径,只需比较从上面和左边到达该位置的所有路径中,路径上的数之和最小的,然后将该位置的值加上路径上所有数之和的最小值即可。
  • 重复上述操作,直到遍历到右下角的位置,此时右下角位置上的值即为从左上角到右下角的所有路径中,路径上的数之和最小的一条路径上所有数的和。
代码示例
def minPathSum(mat):
    m = len(mat)
    n = len(mat[0])
    # 初始化第一行和第一列
    for j in range(1,n):
        mat[0][j] += mat[0][j-1]
    for i in range(1,m):
        mat[i][0] += mat[i-1][0]
    # 计算每个位置到达的最小路径和
    for i in range(1,m):
        for j in range(1,n):
            mat[i][j] += min(mat[i-1][j], mat[i][j-1])
    # 构造最小路径
    path = []
    i,j = m-1,n-1
    path.insert(0, mat[i][j])
    while i>0 or j>0:
        if i == 0:
            j -= 1
        elif j == 0:
            i -= 1
        elif mat[i-1][j] < mat[i][j-1]:
            i -= 1
        else:
            j -= 1
        path.insert(0, mat[i][j])
    # 输出路径
    print('Path:', '->'.join(str(p) for p in path))
    return mat[m-1][n-1]

代码中,首先处理了第一行和第一列的初始值。然后使用双重循环遍历整个矩阵,计算到达每个位置上的最小路径和,并将最小路径和累加到该位置的值上。最后,根据矩阵中每个位置的值构造最小路径。