返回

在崎岖的三角形中寻觅最平坦之路——最小路径和解析

后端

在这篇文章中,我们将共同开启一段探索之旅,深入了解动态规划算法的神奇之处。我们将以一道颇具挑战性的力扣题作为切入点——120. 三角形最小路径和。在这道题中,您需要找到从三角形顶点到底部的路径,使其路径和最小。我们将在本文中详细讲解如何使用动态规划算法轻松解决此题。

动态规划算法简介

动态规划算法是一种高效的算法设计技术,它通过将问题分解成更小的子问题并逐步求解的方式,解决了具有最优子结构和重叠子问题的复杂问题。动态规划算法的关键在于将问题分解成子问题,并以自底向上的方式逐步求解,将子问题的解作为基础,逐步构建出整个问题的解。

问题分解

为了解决最小路径和问题,我们将三角形分解成一系列的子问题。每个子问题都代表从三角形顶点到某个特定位置的最短路径和。我们将从三角形的底部开始,逐步向上分解问题,直到到达顶点。

状态定义

对于每个子问题,我们定义状态f(i, j)表示从三角形顶点到位置(i, j)的最短路径和。其中,i表示从上往下数的层数,j表示从左往右数的位置。

状态转移方程

为了求解状态f(i, j),我们需要考虑从两个方向到达(i, j)的可能性。一种是从(i+1, j)向下移动,另一种是从(i+1, j+1)向下移动。我们选择其中路径和较小的那条路径,作为f(i, j)的值。状态转移方程如下:

f(i, j) = min(f(i+1, j), f(i+1, j+1)) + triangle[i][j]

边界条件

对于三角形的底部,即i = n-1时,状态f(i, j)的值等于三角形第n层第j个元素的值。

算法流程

  1. 初始化:将状态f(i, j)的值初始化为无穷大,表示尚未计算。
  2. 从三角形的底部开始,逐层向上计算状态f(i, j)的值。
  3. 对于每个位置(i, j),根据状态转移方程计算f(i, j)的值。
  4. 直到到达三角形的顶点,即i = 0。
  5. 最终的最小路径和为f(0, 0)。

代码实现

def minimumTotal(triangle):
  """
  :type triangle: List[List[int]]
  :rtype: int
  """

  n = len(triangle)

  # Initialize the dp table
  dp = [[0] * i for i in range(1, n + 1)]

  # Initialize the bottom row of the dp table
  for i in range(n):
    dp[n - 1][i] = triangle[n - 1][i]

  # Iterate from the bottom of the triangle to the top
  for i in range(n - 2, -1, -1):
    for j in range(i + 1):
      # Calculate the minimum path sum for the current cell
      dp[i][j] = min(dp[i + 1][j], dp[i + 1][j + 1]) + triangle[i][j]

  # Return the minimum path sum from the top of the triangle
  return dp[0][0]

结语

至此,我们已经成功地解决了最小路径和问题。希望通过本文,您对动态规划算法有了更深入的了解。动态规划算法在解决许多具有最优子结构和重叠子问题的复杂问题时,都有着广泛的应用。如果您想在算法领域更进一步,我强烈建议您深入学习动态规划算法,它将成为您解决复杂问题的有力工具。