LeetCode热题(JS版) - 64. 最小路径和

79 阅读1分钟

题目

给定一个包含非负整数的 m x n 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。

说明:每次只能向下或者向右移动一步。

示例 1:

image.png

输入:grid = [[1,3,1],[1,5,1],[4,2,1]]
输出:7
解释:因为路径 13111 的总和最小。

示例 2:

输入:grid = [[1,2,3],[4,5,6]]
输出:12

思路

根据题目描述,本题使用动态规划算法。具体实现步骤如下:

  • 定义一个二维数组 dp,其中 dp[i][j]dp[i][j] 表示从左上角到网格中第 i 行、第 j 列的位置的最小路径和。
  • 对于第一行和第一列的元素,由于它们只能由相邻的元素向右或向下移动而来,因此它们的最小路径和即为前一个元素的最小路径和加上当前元素的值。
  • 对于其他位置的元素,可以由其相邻的上方和左方元素向下或向右移动而来,因此转移方程为 dp[i][j]=Math.min(dp[i1][j],dp[i][j1])+grid[i][j]dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j]
  • 最后,最小路径和即为 dp[m1][n1]dp[m - 1][n - 1],其中 m 和 n 分别为网格的行数和列数。

下面是 Typescript 的代码实现:

function minPathSum(grid: number[][]): number {
  const m = grid.length
  const n = grid[0].length
  
  // 初始化
  for (let i = 1; i < m; i++) {
    grid[i][0] += grid[i - 1][0]
  }
  for (let j = 1; j < n; j++) {
    grid[0][j] += grid[0][j - 1]
  }

  // 状态转移
  for (let i = 1; i < m; i++) {
    for (let j = 1; j < n; j++) {
      grid[i][j] += Math.min(grid[i - 1][j], grid[i][j - 1])
    }
  }

  return grid[m - 1][n - 1]
}

image.png

复杂度分析

  • 时间复杂度:O(n),其中 n 表示输入数据的大小。

  • 空间复杂度:O(1),不需要使用额外的空间。