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

分析

这道题采用动态规划,dp[i][j]表示从第0行到第i行以triangle[i][j]元素结尾的最小sum和,而到达第i行的最小sum和是min{dp[i][j]|0<=j<triangle.size()-1}.

状态转移方程,如果triangle[i][j]是该行的第一个,即j=0,则dp[i][j]=dp[i-1][j]+triangle[i][j];

如果triangle[i][j]是该行的最后一个数,即j=triangle[i].size()-1,则dp[i][j]=dp[i-1][j-1]+triangle[i][j];

否则,dp[i][j]=min(dp[i-1][j-1],dp[i-1][j])+triangle[i][j];

const int inf=999999;
class Solution {
public:
    int minimumTotal(vector<vector<int>>& triangle) {
        vector<vector<int>> dp;
        for(int i=1;i<=triangle.size();i++){
            vector<int> vi(i,inf);
            dp.push_back(vi);
        }
        dp[0][0]=triangle[0][0];
        int minvalue=dp[0][0];
        for(int i=1;i<triangle.size();i++){
            minvalue=inf;
            for(int j=0;j<triangle[i].size();j++){
                if(j==0) 
                   dp[i][j]=dp[i-1][j]+triangle[i][j];
                else if(j==triangle[i].size()-1)
                   dp[i][j]=dp[i-1][j-1]+triangle[i][j];
                else
                   dp[i][j]=min(dp[i-1][j-1],dp[i-1][j])+triangle[i][j];     
                minvalue=min(minvalue,dp[i][j]);
            } 
        }
        return minvalue;
    }
};

空间复杂度为O(n)的,n是行数的解法如下

const int inf=999999;
class Solution {
public:
    int minimumTotal(vector<vector<int>>& triangle) {
        vector<int> dp(triangle.size(),inf);
        dp[0]=triangle[0][0];
        int minvalue=dp[0];
        for(int i=1;i<triangle.size();i++){
            minvalue=inf;
            for(int j=0;j<triangle[i].size();j++){
                if(j==0) 
                   dp[j]=triangle[i-1][j]+triangle[i][j];
                else if(j==triangle[i].size()-1)
                   dp[j]=triangle[i-1][j-1]+triangle[i][j];
                else
                   dp[j]=min(triangle[i-1][j-1],triangle[i-1][j])+triangle[i][j];     
                minvalue=min(minvalue,dp[j]);
            } 
            triangle[i]=dp;
        }
        return minvalue;
    }
};

写法更简洁,是从底部向上更新dp的写法。

class Solution {
public:
    int minimumTotal(vector<vector<int> > &triangle) 
    {
        vector<int> mini = triangle[triangle.size()-1];
        for ( int i = triangle.size() - 2; i>= 0 ; --i )
            for ( int j = 0; j < triangle[i].size() ; ++ j )
                mini[j] = triangle[i][j] + min(mini[j],mini[j+1]);
        return mini[0];
    }
};
原文地址:https://www.cnblogs.com/A-Little-Nut/p/10055641.html