LeetCode---120. Triangle

LeetCode—120. Triangle

题目

https://leetcode.com/problems/triangle/description/
给出一个数字组成的三角形,寻找从顶部到低层的最小和路径的和。但要求只能是相邻两层的相邻数字,(不然的话就成了每层选最小值了,,)例如:
LeetCode---120. Triangle_第1张图片

另外,如果只是用O(n)的额外空间,将是bonus point。

思路及解法

这是一道动态规划的题。但是因为第一次接触,所以这里希望多写几种解法。

方法一

从上至下改变三角形,也就是其中的数字会发生改变。一般的思考过程是这样的,当沿着从上至下的方式选择路径的时候,我们把上一层的数字对应加到下面一层,然后用改变数值的下一层继续向下加,直到最后一层。最后,我们只要从加完的最后一层中选择最小的数值就行了,它就是最小路径的和。因为题目要求是得到最小路径的和,所以我们并不需要逆着去吧路径找出来。下面这张图片说明了这种方法
LeetCode---120. Triangle_第2张图片
在写代码的时候有几个小点需要注意一下:1.每个下层的两端元素实际上只能与上一层的两端元素相加,因为题目要求相邻元素。2.除两端元素如何循环作和。
但是这种方法的效率比较低,只能15%左右

方法二

这次用从下到上的思路,同时不改变原始三角形的方法。用一个额外的一维数组来存储作和的结果,初始化为三角形最下面一层,从下到上的过程中每次都将作和的结果放到这个数组的前面的位置,这样到顶层迭代完成后,数组的第一个元素就是我们想要的结果。
从下到上的思路与从上到下的思路本质上一样,只不过每次从下一层的两个相邻的数中选择较小的加到上一层的数上面。

//方法一
class Solution {
    public int minimumTotal(List> triangle) {
        int height = triangle.size();
        if(height == 0) return 0;
        if(height == 1) return triangle.get(0).get(0);
        
        List upList = triangle.get(0);
        for(int i=0; i downList = triangle.get(i+1);
            downList.set(0, upList.get(0)+downList.get(0));
            for(int j=1; j<=i; j++){
                int value = Math.min(upList.get(j-1), upList.get(j)) + downList.get(j);
                downList.set(j, value);
            }
            downList.set(i+1, upList.get(i)+downList.get(i+1));
            upList = downList;
        }
        int minimum = upList.get(0);
        for(int i=1; i
方法二
class Solution {
    public int minimumTotal(List> triangle) {
        int height = triangle.size();
        if(height == 0) return 0;
        if(height == 1) return triangle.get(0).get(0);
        
        int[] dp = new int[height];
        for(int i=height-1; i>=0; i--){
            for(int j=0; j<=i; j++){
                if(i==height-1) dp[j] = triangle.get(i).get(j);
                else dp[j] = Math.min(dp[j], dp[j+1])+triangle.get(i).get(j);
            }
        }
        return dp[0];
    }
}

你可能感兴趣的:(LeetCode---120. Triangle)