【LeetCode】每日一题

97 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第15天,点击查看活动详情

120. 三角形最小路径和

给定一个三角形 triangle ,找出自顶向下的最小路径和。

每一步只能移动到下一行中相邻的结点上。相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 + 1 的两个结点。也就是说,如果正位于当前行的下标 i ,那么下一步可以移动到下一行的下标 i 或 i + 1 。

「示例1:」
输入:triangle = [[2],[3,4],[6,5,7],[4,1,8,3]]
输出:11
解释:如下面简图所示:
   2
  3 4
 6 5 7
4 1 8 3
自顶向下的最小路径和为 11(即,2 + 3 + 5 + 1 = 11)。
「示例2:」
输入:triangle = [[-10]]
输出:-10
「提示:」
1. 1 <= triangle.length <= 200
2. triangle[0].length == 1
3. triangle[i].length == triangle[i - 1].length + 1
4. -104 <= triangle[i][j] <= 104

解题思路

思路:从三角形最后一层开始向上遍历,每个数字的最小路径和是它下面两个数字中的较小者加上它本身
​
复杂度分析:时间复杂度O(n^2),空间复杂O(n)

代码实现

const minimumTotal = (triangle) => {
    const h = triangle.length;
    // 初始化dp数组
    const dp = new Array(h);
    for (let i = 0; i < h; i++) {
        dp[i] = new Array(triangle[i].length);
    }
​
    for (let i = h - 1; i >= 0; i--) { //自底而上遍历
        for (let j = 0; j < triangle[i].length; j++) { //同一层的
            if (i == h - 1) {  // base case 最底层
                dp[i][j] = triangle[i][j];
            } else { // 状态转移方程,上一层由它下面一层计算出
                dp[i][j] = Math.min(dp[i + 1][j], dp[i + 1][j + 1]) + triangle[i][j];
            }
        }
    }
    return dp[0][0];
};
​
​
//状态压缩
const minimumTotal = (triangle) => {
    const bottom = triangle[triangle.length - 1];
    const dp = new Array(bottom.length);
    // base case 是最后一行
    for (let i = 0; i < dp.length; i++) {
        dp[i] = bottom[i];
    }
    // 从倒数第二列开始迭代
    for (let i = dp.length - 2; i >= 0; i--) {
        for (let j = 0; j < triangle[i].length; j++) {
            dp[j] = Math.min(dp[j], dp[j + 1]) + triangle[i][j];
        }
    }
    return dp[0];
};

如果你对这道题目还有疑问的话,可以在评论区进行留言;