LeetCode 32 Triangle

Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below.

For example, given the following triangle

[
     [2]
    [3,4]
   [6,5,7],  
  [4,1,8,3]
]
The minimum path sum from top to bottom is 11 (i.e., 2 + 3 + 5 + 1 = 11).

NOTE:

Bonus point if you are able to do this using only O(n) extra space, where n is the total number of rows in the triangle.

分析:

又是最优化问题,想到DP。

接下来寻找子问题以及状态转移方程。

子问题一般分为两种:

1,从开头到 i ,并由 i 的最优解推出 i+1 的最优解,则表的最后一个元素最优解;

2,从 i 到结尾,并由 i+1 的最优解能够推出 i 的最优解,则表的第一个元素就是最优解。

(上面的表述不够严谨,也可能是根据 i-2, i-1, i 三个状态才能组合成 i+1的状态,大概意思哈)。


具体这个问题,子问题大概就应该按层数找吧。

假设按层数直接以 [0, i] 的最小路径和,没法由这个最优解推出[0, i+1] 的最优解,换成每个位置的最优解,则可以往下继续推。


我们先从从上向下来, 

基本的思路是维持一个len 等于最后一行长度的数组array,初始为0.

则 array[ i ] = min{ array[i-1]+curr[i], array[i]+curr[i] }

用这种方法,需要注意两点:

1,注意i=0时,i-1的判断,否则数组下标要溢出;

2,每更新一层要从后向前来,因为如果从前往后来,更新了array[i] 在更新 array[i+1]的时候还要用原来的array[i]。

这样,到最后一层,遍历array数组找到最小值就是我们要的结果。


那么从下往上来呢?

思路还是维持一个len等于最后一行长度的数组array,这个初始值就要等于最后一行了。

则 array[ i ] = min{ curr[i]+array[i], curr[i]+array[i+1]}

最后,array[ 0 ]就是要的答案了。


感觉两种都行,下面是从下往上的代码。

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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值