📜  当正好允许两个左移时,在2D矩阵中找到最大路径总和(1)

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

在2D矩阵中找到最大路径总和

介绍

在2D矩阵中找到最大路径总和是一个经典的动态规划问题。给定一个矩阵,每个格子里有一个值,你需要找到一条从左上角到右下角的路径,使得沿路径走过的值得总和最大。

需要注意的是,题目中给定的是“当正好允许两个左移时”,这意味着在横向移动时不能连续左移两次,也就是说,只能有一次左移。

解决方案
动态规划

该问题可以使用动态规划来解决。首先,我们定义一个二维数组 $dp$,其中 $dp_{i,j}$ 表示从起点到 $(i,j)$ 这个格子的最大路径总和。那么,$dp_{i,j}$ 可以从 $dp_{i-1,j}$ 和 $dp_{i,j-1}$ 转移而来。具体转移方程如下:

$$ dp_{i,j} = \max(dp_{i-1,j}, dp_{i,j-1}) + a_{i,j} $$

其中,$a_{i,j}$ 表示 $(i,j)$ 这个格子的值。

需要注意的是,由于题目要求不能连续左移两次,我们需要对状态转移方程做出一些修改,具体来说,当 $i \geq 2$ 且 $j = 1$ 时,$dp_{i,j}$ 的值应该从 $dp_{i-2,m}$($m$ 为最大列数)转移而来。转移方程如下:

$$ dp_{i,j} = \max(dp_{i-1,j}, dp_{i,j-1}) + a_{i,j} \ (j \neq 1) \ dp_{i,j} = \max(dp_{i-1,j}, dp_{i-2,m}) + a_{i,j} \ (j = 1 \ \mathrm{and} \ i \geq 2) $$

最终,最大路径总和就是 $dp_{n,m}$($n$ 为最大行数,$m$ 为最大列数)。

代码实现

下面是 Python 语言的动态规划的实现:

def maxPathSum(matrix):
    n, m = len(matrix), len(matrix[0])
    dp = [[0] * m for _ in range(n)]
    dp[0][0] = matrix[0][0]
    for i in range(1, n):
        if i == 1:
            dp[i][0] = matrix[i][0] + dp[i-1][0]
        else:
            dp[i][0] = matrix[i][0] + max(dp[i-1][0], dp[i-2][m-1])
    for j in range(1, m):
        dp[0][j] = matrix[0][j] + dp[0][j-1]
        for i in range(1, n):
            if j == 1:
                dp[i][j] = matrix[i][j] + max(dp[i-1][j], dp[i][j-1])
            else:
                dp[i][j] = matrix[i][j] + max(dp[i-1][j], dp[i][j-1])
    return dp[n-1][m-1]

该函数的输入参数为一个二维矩阵,输出最大路径总和。

需要注意的是,代码中的 $n$ 和 $m$ 对应题目中的最大行数和最大列数,而 $i$ 和 $j$ 从 $0$ 开始取值,所以在转移方程中需要加 $1$。另外,由于 Python 的数组下标可以为负,所以我们并不需要特别处理 $j = 0$ 的情况。

时间复杂度分析

由于我们需要遍历整个矩阵,所以时间复杂度是 $O(nm)$,其中 $n$ 和 $m$ 分别为矩阵的行数和列数。

空间复杂度分析

由于我们需要维护一个二维数组 $dp$,所以空间复杂度是 $O(nm)$。

总结

在2D矩阵中找到最大路径总和是一个经典的动态规划问题。对于这个问题,我们可以使用动态规划来解决。需要注意的是,题目中要求不能连续左移两次,因此,需要对状态转移方程做出相应的修改。实现时,我们需要遍历整个矩阵,并维护一个二维数组 $dp$。最终,最大路径总和就是 $dp_{n,m}$。时间复杂度是 $O(nm)$,空间复杂度是 $O(nm)$。