LeetCode 120. 三角形最小路径和 动态规划

今天带来一题经典动态规划问题,LeetCode的120题,就是数塔问题。
LeetCode 120. 三角形最小路径和 动态规划_第1张图片
本来是想从上面往下做的,初始化左右两边即最上面那个点,然后一直有问题,好吧,那就自底向上写吧。
老生常谈,先用递归来写,毕竟写法方便不废脑子,要是能过了最好。
LeetCode 120. 三角形最小路径和 动态规划_第2张图片
但是明显效果不好,答案是对的,但超时,
不过我还是说一下递归吧,首先设置好边界,达到了最后一行的时候,返回所在值是必须的,以及如果x,或y走出去了,那得想办法收回来,怎么办,如果是求最大,返回一个非常小的值, 如果题目都是正数,就返回一个负数,如果求最小,就返回一个很大的值,这样不管如何,函数会自己帮你选择规范的路径。
这题递归的话设置两个边界就行。

但是超时,那就考虑dp。
自底向上,先初始化底部,然后一个一个往上加,每一个点都是最小值,直到累加到了顶点,那就一定是最小值。无后效性,可以求出最优解。
LeetCode 120. 三角形最小路径和 动态规划_第3张图片
效率一般般,可以优化,显然,时间已经无法优化了,从空间着手吧,以前讲过可以使用滚动数组,这里我们就化二维变成一维。我们可以想一下,按照上面的说法,每一层求出来的都是最小值了,无后效性!和背包问题不同,我们已经不需要用过的数字了,替换掉就行,这样就不停的更替,更新为新的最小值的一维数组。
效率还不错。
LeetCode 120. 三角形最小路径和 动态规划_第4张图片
这是代码。

class Solution {
    public int minimumTotal(List> triangle) {
        int m = triangle.size();
        int[] dp = new int[m + 1];
        for(int i = 0; i < m; i ++) {
            dp[i] = triangle.get(m - 1).get(i);
        }
        for(int i = m - 2; i >= 0; i --) {
            for(int j = 0; j <= i; j ++) {
                dp[j] = Math.min(dp[j], dp[j + 1]) + triangle.get(i).get(j);
            }
        }
        return dp[0];
    }
}

你可能感兴趣的:(leetcode)