LeetCode-64 不同路径(III)

131 阅读3分钟

一、题目描述

dp6.png

二、题目翻译

给定一个二维网格,在某些条件A的限制下,请找出一条从起点到终点的路径,使得路径上的数字总和最小。

条件A:机器人每次只能向下或者向右移动一步。

三、再来点用例

dp7.png

四、思路讲解

我们以如下二维表格来进行分析:

dp8.png

其中,1是起点9是终点

以9的角度来看,能够到达9的路径有2个,分别是 86。但是这里会出现一个问题,我是取8 还是 6?

4.1、8还是6?

这里肯定会有人说,当然取6了,因为6更小,且符合题意。那如果是下面这样的二维网格呢?

dp9.png

那可就不是取6了,那得是取8,路径和才能最小,且符合题意(此时的路径集合:(0, 0) -> (1, 0) -> (2, 0) -> (2, 1) -> (2, 2))

所以,经过上面的分析,我们会发现,取8还是取6,是由下面的思路决定的:

1、到达8的最小路径和,到达6的最新路径和,他俩谁小取谁。
2、最小路径和 有时并不等于 网格上的值。

那么,5、6、8的网格的分析思路一定是与9的网格的思路是一样的,因为他们都有一个共同的特点,那就是到达5、6、8、9这四个网格中的一个,都有2条路径

那么我们照着这个思路可以写出如下代码:

    var minPathSum = function (grid){
        let xLength = grid.length;
        let yLength = grid[0].length;
        // 创建dp数组,用于存放二维网格中每个单元格被到达时的最小路径数。
        let dp = new Array(xLength).fill(1).map(item => new Array(yLength).fill(1));
        dp[0][0] = grid[0][0];
        for (let x = 0; x < xLength; x++){
            for (let y = 0; y < yLength; y++){
                if (x > 0 && y > 0){
                    dp[x][y] = Math.min( dp[x-1][y], dp[x][y-1] ) + grid[x][y];
                }
            }
        }
    };

4.2、2和3网格如何取值?

dp9.png

无论是2还是3,我们发现根据题意,他们的入口只能有1个,就是一直向右。

以2为举例,2的最小路径和 == 1的网格值 + 2的网格值。

以3为举例,3的最小路径和 == 2的最小路径和 + 3的网格值。

这里依然会有一个问题,3的最小路径和 == 2的最小路径和 + 3的网格值。我们这里为什么取的是2的最小路径和,而不是2的网格值?

答案:因为网格值是不可信的,2的网格值有可能是任意值,只不过在我们的例子中,2网格值正好等于2,而2的最小路径和等于3。

基于上面的分析:我们补全剩余代码:

    var minPathSum = function (grid){
        let xLength = grid.length;
        let yLength = grid[0].length;
        // 创建dp数组,用于存放二维网格中每个单元格被到达时的最小路径数。
        let dp = new Array(xLength).fill(1).map(item => new Array(yLength).fill(1));
        dp[0][0] = grid[0][0];
        for (let x = 0; x < xLength; x++){
            for (let y = 0; y < yLength; y++){
                if (x > 0 && y > 0){
                    dp[x][y] = Math.min( dp[x-1][y], dp[x][y-1] ) + grid[x][y];
                } else if (x == 0 && y > 0){
                    // 横轴第0行
                    dp[x][y] = dp[x][y-1] + grid[x][y];
                } else if (x > 0 && y == 0){
                    // 纵轴第0行
                    dp[x][y] = dp[x-1][y] + grid[x][y];
                }
            }
        }
        return d[xLength - 1][yLength - 1];
    };

跑一下上面的代码,我们发现,得到的结果都是正确的。

五、最后

好啦,又到了文章结尾了,我们下期再见啦。