返回

用代码解决[到达终点](/articles/reaching-the-end/)难题

后端

代码问题常常令人挠头,需要我们动脑思考,寻找巧妙的解决之道。在今天的文章中,我们将深入剖析一道经典算法题——「到达终点」,并分享用代码解决这一难题的详细过程。

题目解析

到达终点

给定一个包含非负整数的 n x m 网格,其中每个整数代表该位置的障碍值。如果从位置 (0, 0) 出发,可以向右或向下移动,且每一步只能增加移动方向对应的障碍值,那么抵达位置 (n-1, m-1) 的最小障碍值是多少?

代码实现

思路解析

解决此题的关键在于使用动态规划。我们创建一个二维数组 dp,其中 dp[i][j] 表示从 (0, 0) 到 (i, j) 的最小障碍值。

代码实现

def min_obstacle_value(grid):
  """
  :param grid: list[list[int]]
  :return: int
  """
  n, m = len(grid), len(grid[0])
  dp = [[float('inf') for _ in range(m)] for _ in range(n)]

  # 初始化第一行和第一列
  dp[0][0] = grid[0][0]
  for i in range(1, n):
    dp[i][0] = dp[i-1][0] + grid[i][0]
  for j in range(1, m):
    dp[0][j] = dp[0][j-1] + grid[0][j]

  # 计算其余元素的最小障碍值
  for i in range(1, n):
    for j in range(1, m):
      dp[i][j] = min(dp[i-1][j] + grid[i][j], dp[i][j-1] + grid[i][j])

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

运行结果

我们以一个示例网格作为输入:

grid = [[1, 3, 1],
       [1, 5, 1],
       [4, 2, 1]]

调用 min_obstacle_value 函数,得到最小障碍值为 7

性能分析

该代码的时间复杂度为 O(n * m),其中 n 和 m 分别为网格的行数和列数。空间复杂度也是 O(n * m),因为我们需要创建一个二维数组 dp

总结

通过动态规划,我们有效地解决了「到达终点」问题。利用 dp 数组存储已计算的最小障碍值,我们可以快速求解出从起点到终点的最优路径。这种方法不仅清晰易懂,而且性能优异。希望这篇文章能帮助你理解算法的巧妙应用,提升你解决问题的能力。

扩展

  • 尝试实现其他动态规划算法来解决其他类型的代码问题。
  • 探讨不同代码问题中动态规划的应用场景。
  • 了解动态规划的原理和局限性。