返回

LeetCode 64 最小路径和:了解问题本质轻松应对

前端

正视挑战:了解问题的本质

最小路径和,乍一听像是个棘手的问题,实际上它反映的是动态规划的核心本质——在解决问题时,需要将大问题拆解成更小的子问题,并在子问题得到解决后逐步向上汇总,最终解决大问题。

破解密码:动态规划的妙用

解决最小路径和问题,需要从左上角的单元格出发,逐步向右下角移动,并记录经过每个单元格的路径和。这个过程,实际上就是动态规划中的状态转移方程:

f(i, j) = min(f(i-1, j), f(i, j-1)) + grid(i, j)

其中,f(i, j)表示从左上角到单元格(i, j)的最小路径和,grid(i, j)表示单元格(i, j)的值。

划重点:状态转移方程及特殊情况

状态转移方程的核心是确定当前单元格的最小路径和,需要用到之前单元格的最小路径和,并加上当前单元格的值。

需要注意的是,对于第一行和第一列的单元格,由于它们没有上一个或左一个单元格,因此需要特殊处理。

见证奇迹:解题步骤及代码实现

步骤一:初始化

创建一个二维数组dp,其大小与网格grid相同,dp[i][j]表示从左上角到单元格(i, j)的最小路径和。将dp[0][0]设为grid[0][0]。

步骤二:动态规划

对于i从1到m-1,进行如下操作:

  • 计算dp[i][0],其值为grid[i][0]加上dp[i-1][0]。
  • 对于j从1到n-1,进行如下操作:
    • 计算dp[i][j],其值为grid[i][j]加上较小的dp值,即min(dp[i-1][j], dp[i][j-1])。

步骤三:输出结果

返回dp[m-1][n-1],即从左上角到右下角的最小路径和。

附上代码示例,方便理解:

def min_path_sum(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] = grid[i][0] + dp[i-1][0]

  # 计算第一列
  for j in range(1, n):
    dp[0][j] = grid[0][j] + dp[0][j-1]

  # 计算其他单元格
  for i in range(1, m):
    for j in range(1, n):
      dp[i][j] = grid[i][j] + min(dp[i-1][j], dp[i][j-1])

  return dp[m-1][n-1]

用心感受:动态规划的精髓

通过这道题,你掌握了动态规划的思想和步骤,以后遇到类似问题,便能轻松应对。动态规划,就是将复杂问题分解成小块,并逐步解决,是计算机科学中至关重要的算法技术之一。