Leetcode:120.三角形最小路径和

133 篇文章 0 订阅

给定一个三角形,找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的结点上。

例如,给定三角形:

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

自顶向下的最小路径和为 11(即,3 + 1 = 11)。

说明:

如果你可以只使用 O(n) 的额外空间(n 为三角形的总行数)来解决这个问题,那么你的算法会很加分。

解题思路:

动态规划(DP)。杨辉三角的一个特点,就是可分成(分成用词不准,但是很形象)一个顶点+2个小的杨辉三角。例如:     

       [2],                               

     [3,4],                                                  [3]                           [4]

    [6,5,7], ========>           [2]     +     [6,5]             +         [5,7]

  [4,1,8,3]                                             [4,1,8]                     [1,8,3]

                                                              

假如我们能够找到n-1层杨辉三角的最短路劲解法f(n-1),那么f(n)=root+min(f(n-1),f(n-1)),这两个n-1分别是左右两个三角解法。

很显然,有点灵性的小伙伴就已经能够发现动态规划的气息了,接下来还缺的一个重要东西就是边界条件(递归必须要有边界条件)。当层数为2的时候,可以直接return val+min(left,right)。

以上就已经把问题解决了,根据说明,只使用O(n)的空间,are you sure? 我仔细想了想,完全想不到哪里需要空间,事实上一个都不需要! 事实上只需要从倒数第二行(当然,如果有的话)开始,往上逐行修改原有数组中的值即可,这样一来递归也消去了。如果不明白的话看看下面的流程应该就懂了。

       [2],                               

     [3,4],                                                 

    [6,5,7], ===>         

  [4,1,8,3]   

       [2],                               

     [3,4],                                                 

    [7,6,10], ===>         

  [4,1,8,3]   

       [2],                               

     [9,10],                                                 

    [7,6,10], ===>         

  [4,1, 8, 3] 

       [11],                               

     [9,10],                                                 

    [7,6,10], ===>         

  [4,1, 8, 3] 

最后    return 第一行元素。

                  

C++代码
class Solution {
public:
    int minimumTotal(vector<vector<int>>& triangle) {
        int size = triangle.size();
        if (size <= 0) return 0;
        //从倒数第二行开始
        for (int i = size - 1; i >= 1; i--) {
            for (int j = 1; j <= i; j++) {
                triangle[i - 1][j - 1] += (triangle[i][j - 1] < triangle[i][j] ? triangle[i][j - 1] : triangle[i][j]);
            }
        }
        return triangle[0][0];
    }
};

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值