LeetCode-120 三角形最小路径和

87 阅读1分钟

一、题目描述

LeetCode-120.jpg

这题乍一看我还以为是求每一项的最小值,然后加和呢...

题目翻译:

求数组的最后一项里,对应加和数最小的值是多少?

二、示例讲解

LeetCode-120-01.jpg

    A2(第一层) -> 2
    A3(第二层) -> 3 + 2
    A4(第二层) -> 4 + 2
    A6(第三层) -> 6 + 3 + 2
    A5(第三层) -> Math.min(5 + A3, 5 + A4)
    A7(第三层) -> Math.min(7 + A4)
    A4(第四层) -> A6 + 4
    A1(第四层) -> Math.min(A6 + 1, A5 + 1)
    A8(第四层) -> Math.min(A5 + 8, A7 + 8)
    A3(第四层) -> A7 + 3

三、思路讲解

其实上面的思路已经非常清晰了,就是层层递归,下一层的值一定是由上一层得来的。

那么每一层里的每一项的值如何存呢?

我们可以使用二维数组,三角形结构其实也是二维数组结构,看下面的图就清晰了:

   2                           2 0 0 0
  3 4                  转换    3 0 0 0
 6 5 7                ----->   6 5 7 0
4 1 8 3                        4 1 8 3

四、代码实现

    var minimumTotal = function(triangle) {
        let dp = new Array(triangle.length).fill(0).map(item => new Array(triangle.length).fill(0)); // 初始化二维数组
        // 最后对比dp数组里的每一项对应的最小值即可
        dp[0][0] = triangle[0][0];
        for (let x = 0; x < triangle.length; x++){
            // 遍历横轴
            for (let y = 0; y < triangle.length; y++){
                // 遍历纵轴

                // 1、第一列的值只能由上一列的第一个值获取
                if (y == 0 && x > 0){
                    dp[x][y] = dp[x - 1][y] + triangle[x][y];
                } else if ( (y == triangle[x].length - 1) && x > 0 ){
                    // 2、每行上的最后一个值,一定是由上一行的最后一个值得来的
                    dp[x][y] = dp[x - 1][y - 1] + triangle[x][y];
                } else if (x > 0 && ( y > 0 && y < triangle[x].length - 1 ) ) {
                    // 3、剩下的中间部分,路径都有2个,分别是左上、右上,取值为他俩中间取小
                    dp[x][y] = Math.min( dp[x - 1][y-1], dp[x - 1][y] ) + triangle[x][y];
                }
            }
        }
        return Math.min.apply(Array, dp[triangle.length - 1])
    };

五、最后

本期算法讲解到这里就结束啦,下次再见喽