LeetCode 热题 HOT — 最小路径和

104 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第 17 天,点击查看活动详情

最小路径和

原题地址

给定一个包含非负整数的 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

提示:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 200
  • 0 <= grid[i][j] <= 100

思路分析

  1. 定义一个 res 数组,其中 res[i][j] 表示从左上角走到 (i, j) 的最小路径;
  2. 题目规定,只能向右或者向下移动,因此想要走到 (i, j),如果向下走一步到达,就是从 (i-1, j) 走过来;若向右走一步到达,就是从 (i, j-1) 走过来;
  3. 按照2得出,res[i][j] += Math.min(res[i-1][j], res[i][j-1]);
  4. 然后来确定初值,若 m 或者 n 有一个为 0,则都只有一条路径可以到达,到达的最短路径也就是在这条线上的各个节点之和,那对于剩余的节点来说,res 中的值都为 grid 中对应位置的值,这样可以确保计算的时候,加上了自身的节点数,当然也可以使用 grid[i][j] 来替代;
  5. 按照步骤三的公式,最终计算得到 res

AC 代码

/**
 * @param {number[][]} grid
 * @return {number}
 */
var minPathSum = function(grid) {
    const m = grid.length
    const n = grid[0].length
    const res = grid
    let tempM = 0, tempN = 0
    for (let i = 0; i < m; i++) {
        tempM += grid[i][0]
        res[i][0] = tempM
    }
    for (let j = 0; j < n; j++) {
        tempN += grid[0][j]
        res[0][j] = tempN
    }
    for (let i = 1; i < m; i++) {
        for (let j = 1; j < n; j++) {
            res[i][j] += Math.min(res[i][j - 1],res[i-1][j])
        }
    }
    
    return res[m - 1][n - 1]
};

结果:

  • 执行结果: 通过
  • 执行用时:272 ms, 在所有 JavaScript 提交中击败了6.21%的用户
  • 内存消耗:49.9 MB, 在所有 JavaScript 提交中击败了5.02%的用户
  • 通过测试用例:61 / 61

总结

上篇文章中写了,从左上角到右下角的路径总数,因此看到这个题目的第一想法就是,在所有的路径中找到最小的数字总和。在改造的过程中,首先是要确定 res 的初值,这决定后续节点的计算。

定义了两个临时变量,在计算在第一行和第一列中各个节点的路径和。在后续处理的过程中,因为给 res 赋的初值每个节点上都为 0,因此在使用公式计算时,会出错。在排查后才得到了正确的答案。

虽然不是一个最佳的答案,但是也是从上一题衍生后,一步一步踩坑得出来的结果。

END