120. 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.

题意:

给定一个三角形,找到从顶端到低端最短的路径和。每一步只能移动到下一行的相邻格子中。

note:

加分点:只使用大小为n的额外内存空间来辅助,n的大小为三角形中的所有元素个数。


思路一:

DP问题,动态规划问题。除了三角形两边的各个元素之外,中间的各个元素都有上一层中相邻的两两个元素可供选择,按题意,两个元素中选择最小的。从第二层开始,三角形的两边都是直接累加的,中间的元素累加选择上一层中与该元素相邻的两个元素的最小值,最后求出的从顶端到低端每一条路径的最小值均存储在最后一层中。遍历循环结束后只需要找出最后一层的最小值即为三角形的最小值路径。

[
     [2],
    [3,4],
   [6,5,7],
  [4,1,8,3]
]
代码:8ms

class Solution {
public:
    int minimumTotal(vector<vector<int>>& triangle) {
        
        int rowm = triangle.size();  //找出三角形层数
        for(int i=1; i<rowm; i++){   //从第二层开始循环累加
            int prem = triangle[i-1].size();  //找到当前层的上一层大小
            int colm = triangle[i].size();  //当前层的大小
            
            triangle[i][0] += triangle[i-1][0];  //三角形左边线的累加
            triangle[i][colm-1] += triangle[i-1][prem-1];  //三角形右边线的累加
            
            for(int j=1; j<colm-1; j++){  //三角形中间元素的累加
                triangle[i][j] += min(triangle[i-1][j-1], triangle[i-1][j]); //上一层与该元素相邻的两元素中的较小值与当前元素累加
            }
        }
        
        int size = triangle[rowm-1].size(); //三角形最后一层大小
        int minTotal = triangle[rowm-1][0];  //假定第一个元素是最小值
        
        for(int i=1; i<size; i++){  //循环遍历三角形最底层,找到最小值即为所求最小值
            minTotal = min(minTotal, triangle[rowm-1][i]);
        }
        
        return minTotal;
    }
};

思路二:

同样采用动态规划,从底向上轮训,这样就可以不用区分三角形的边与其他元素之间的差别,代码也更为精简。从倒数第二层到第一层,每个元素与下一层中与其相邻的两个元素中的最小值进行累加,轮训结束,三角形顶端的元素即为最小路径和。

[
     [2],
    [3,4],
   [6,5,7],
  [4,1,8,3]
]

代码:8ms

class Solution {
public:
    int minimumTotal(vector<vector<int>>& triangle) {
        
        int rowm = triangle.size();  //找出三角形层数
        for(int i=rowm-2; i>=0; i--){  //对每一层轮训
            int colm = triangle[i].size();  //每一层的大小
            for(int j=0; j<colm; j++){  
                triangle[i][j] += min(triangle[i+1][j], triangle[i+1][j+1]); //该层中每个元素与下一层中两个相邻子元素相累加。
            }
        }
        
        return triangle[0][0];
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值