64. 最小路径和
发布日期:2021-05-18 05:02:43 浏览次数:21 分类:精选文章

本文共 1708 字,大约阅读时间需要 5 分钟。

动态规划求解矩阵最小路径和问题

问题描述

在一个给定的矩阵中,每一个格子都有一定的数值。我们需要找到一条路径,使得路径上所有数值的总和最小。路径定义为从左上角到右下角的连续向下或向右移动的过程。

举个例子,假设给定的矩阵如下:

nums = [    [1, 2],    [3, 4]]

那么,可能的路径有两条:

  • 右 → 下:1 + 2 + 4 = 7
  • 下 → 右:1 + 3 + 4 = 8
  • 所以,最小路径和为7。

    动态规划优化思路

    为了高效地解决这个问题,我们可以使用动态规划(Dynamic Programming,简称DP)方法。动态规划的核心思想是将大问题分解为小子问题,一次解决一个子问题,最终得到答案。

    我们可以在矩阵中创建一个二维数组 dp,其中 dp[i][j] 表示到位置(i,j)的最小路径和。

    递推公式

    到位置(i,j)的最小路径和 dp[i][j] 可以通过以下公式计算:

    dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + nums[i][j]

    这个公式的意思是:从上方(i-1,j)或左方(i,j-1)来到当前位置(i,j),然后加上当前位置的数值 nums[i][j]。我们选择最小的那个路径来更新 dp[i][j]

    初始化

    由于递推公式涉及到上方和左方的值,所以我们需要对第一行和第一列进行特殊处理。

    • 第一行(i=0): 从左到右依次计算路径和。
    dp[0][j] = dp[0][j-1] + nums[0][j]
    • 第一列(j=0): 从上到下依次计算路径和。
    dp[i][0] = dp[i-1][0] + nums[i][0]

    这样,递推过程就不会出现数组越界的问题。

    代码实现

    根据以上思路,以下是实现最小路径和的动态规划代码:

    def minPathSum(grid):    """    使用动态规划求解矩阵最小路径和问题        @param grid: m x n 的矩阵    @return: 最小路径和    """    if not grid:        return 0        m = len(grid)    n = len(grid[0]) if m > 0 else 0        # 创建一个 m x n 大小的 DP 表    dp = [[0 for _ in range(n)] for _ in range(m)]        # 初始化    dp[0][0] = grid[0][0]        # 初始化第一行    for j in range(1, n):        dp[0][j] = dp[0][j-1] + grid[0][j]        # 初始化第一列    for i in range(1, m):        dp[i][0] = dp[i-1][0] + grid[i][0]        # 填充DP 表    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[m-1][n-1]

    结果分析

    通过上述动态规划方法,我们可以高效地计算出矩阵中的最小路径和。具体步骤分为以下几个部分:

  • 初始化 DP 表:创建一个同样大小的 dp 表。
  • 处理边界条件:初始化第一行和第一列,因为它们是计算其他单元格的基础。
  • 填充 DP 表:使用递推公式逐个计算每个单元格的值,最终得到 dp[m-1][n-1],即最小路径和。
  • 这种方法的时间复杂度为 O(m x n),空间复杂度为 O(m x n)(用于存储 DP 表)。非常适合处理较大的矩阵问题。

    总结

    动态规划是一种非常有用的算法设计方法,尤其在解决具有重叠子问题的小规模问题时特别有效。在本题中,通过动态规划,我们可以在 O(m x n) 时间复杂度内轻松找到矩阵中的最小路径和。

    上一篇:面试题 08.01. 三步问题
    下一篇:面试题 17.16. 按摩师

    发表评论

    最新留言

    能坚持,总会有不一样的收获!
    [***.219.124.196]2025年05月06日 01时10分57秒