三角形最小/最大路径

题目描述:

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

例如,给定三角形:

[
[2],
[3,4],
[6,5,7],
[4,1,8,3]
]
自顶向下的最小路径和为 11(即,2 + 3 + 5 + 1 = 11)。

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/triangle

问题分析:

这种题拿来一看就知道是动态规划算法了了。

首先我觉得贪心算法貌似不行
贪心的思想是,每次选取当前最短/最大的情况,直到最后得到最优方案。

因此,用动态规划来分析。

因为随着我们走,后边路径可能导致之前走过的路线不再是最优路径。

**

那么很快我们便有了一种解决问题的思路:**

思路:开辟同样大小的三角形(二维数组)

每个位置均保存来到当前位置的最短路径。

这样来看,更直观一点。
在这里插入图片描述

这个很容易了吧:
vv[ i ][ j ] = triangle[ i ][ j ] +
min(a[ i - 1 ][ j ] , vv[ i - 1 ][ j + 1 ]

因此,我们采用自底向上的分析法:
当前位置, 不是从正上方过来,必然从左上方的右边过来。

这样,能够得到二维实时路径长度的数组。我们再从最后一层中选出最小的即可。

我们的上述做法可以解决问题,但时空复杂的均为O(N^2)

2 那么来看优化

当我们每次从上边向下走时,遇到相等的就成了一个难题。

我们自底向上来走,这样无论如何都会走到triagle[0 ][ 0],不用担心多出口。

在自底向上走时,我们顺便保存一下当前的最短路径。

注意:核心想法来了:
既然我们只需要最优的一个路径,那么也就是说,我们每层保存的路径,用于求得新一层路径后后,就没啥暖用了,
那么 我们就将其覆盖掉,

因此 一维数组就可以保存当前层所有方格的最优路径了,

再准确点描述:当来到新一层计算好一个方格的最优路径后,就可以覆盖掉下面那层同列的最优路径了。

你明白了吗?

看看代码你一定就懂了。

class Solution {
public:
    int minimumTotal(vector<vector<int>>& triangle) {
        vector<int> dp(triangle.size()+1,0);//初始化为0
        //为什么需要多一个数组空间,因为每次取两个路径长度比较并提取其中最小的。

       //自底向上
        for(int i=triangle.size()-1; i>=0; i--)
        {
            for(int j=0; j<triangle[i].size(); j++) 
            {
                //每求完一层,新一层数据一旦出来就可以覆盖掉
                //原有数据了,(原数据用不上了)
         dp[j] = min(dp[j],dp[j+1]) +  triangle[i][j];
            }
        }
        return dp[0];
    }
};
发布了98 篇原创文章 · 获赞 13 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_44030580/article/details/105076108
今日推荐