Description
Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below.
Example
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.
Solution 1(C++)
class Solution {
public:
int minimumTotal(vector<vector<int>>& triangle) {
if(!triangle.size() || !triangle[0].size()) return 0;
vector<vector<int>> dp(triangle.size(), vector<int>(triangle[triangle.size()-1].size(), 0));
int minPath=INT_MAX;
for(int i=0; i<triangle.size(); i++){
for(int j=0; j<triangle[i].size(); j++){
if(i==0) dp[i][j]=triangle[i][j];
else if(i>0 && j==0) dp[i][j]=dp[i-1][j]+triangle[i][j];
else if(i>0 && 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];
if(i==triangle.size()-1)
minPath=min(minPath, dp[i][j]);
}
}
return minPath;
}
};
Solution 2(C++)
class Solution {
public:
int minimumTotal(vector<vector<int>>& triangle) {
for(int i = triangle.size() - 2; i >= 0; --i)
{
for(int j = 0; j <= i; ++j)
{
triangle[i][j] += min(triangle[i + 1][j], triangle[i + 1][j + 1]);
}
}
return triangle[0][0];
}
};
算法分析
解法一是自己写的,用动态规划的方法即可。解法二是真的有意思,他和普通的思路不一样,反过来思考,竟然就直接返回triangle[0][0],而不用我解法一中要在最后一行triangle的元素中进行比较,找到minPath。
而且解法二倒过来思考,那么就不用想解法一一样需要注意下一行的元素如果是最开始或者最末尾的位置处,就只能分别由triangle[i-1][j]与triangle[i-1][j-1]得到。返过来就可以套用完全相同的公式。这个是真的有意思。
程序分析
像这种一端到另一端的问题,不要被局限住了,可以尝试换个方向思考。有奇效。