leetcode-120-三角形最小路径和

题目描述:

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

例如,给定三角形:

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

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

说明:

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

 

要完成的函数:

int minimumTotal(vector<vector<int>>& triangle) 

说明:

1、这道题给定一个二维的vector,里面存储了一个三角形,第一行有一个元素,第二行有两个元素,第三行有三个元素……

三角形中有从上到下的路径,每次从上一行的元素到达下一行的元素,只能到达下一行左右位置的两个元素。

要求找到一条路径,使得找到的这条路径上的所有元素的和是最小的。

最后返回这个最小的路径和。

2、这是一道动态规划的题目,我们需要记录每一步的最小路径代价。

笔者没有只使用O(n)的额外空间,而是用了O(n^2)的额外空间,来记录每一个节点的最小路径代价。

初始化的时候,第一行第一个元素的最小路径代价是其本身。

接下来每个元素,要不就是上一行的左边元素的最小路径代价+自身代价,要不就是上一行的右边元素的最小路径代价+自身代价,两者之中取一个小的作为这一个节点的最小路径代价。

如果是第一列的元素,也就是上一行的左边没有元素,那么只能取上一行的右边元素。

同理,如果是最后一列的元素,也只能取上一行的左边元素。

最后,对最后一行的所有元素的最小路径代价做个遍历,找到其中最小的值,返回。

代码如下:(附详解)

    int minimumTotal(vector<vector<int>>& triangle) 
    {
        if(triangle.empty())//如果三角形为空,边界情况
            return 0;
        int hang=triangle.size();
        vector<vector<int>>record=triangle;
        for(int i=0;i<hang;i++)//对三角形的每一行做遍历
        {
            for(int j=0;j<triangle[i].size();j++)//对三角形某一行的每一列进行遍历
            {
                if(i==0&&j==0)//初始化
                    record[i][j]=triangle[i][j];
                else
                {
                    if(j==0)//如果是第一列的元素
                        record[i][j]=record[i-1][j]+triangle[i][j];
                    else if(j==triangle[i].size()-1)//如果是最后一列的元素
                        record[i][j]=record[i-1][j-1]+triangle[i][j];
                    else//如果是中间部分的元素
                        record[i][j]=min(record[i-1][j-1],record[i-1][j])+triangle[i][j];
                }
            }
        }
        int min1=INT_MAX;
        for(int j=0;j<record[hang-1].size();j++)//做遍历,找到最小的路径代价
            min1=min(min1,record[hang-1][j]);
        return min1;
    }

上述代码实测4ms,beats 100.00% of cpp submissions。

猜你喜欢

转载自www.cnblogs.com/king-3/p/10261340.html