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 is11(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.
这道题的意思是给定一个三角形状的二维数组,从上到下求最小路径和。每一步可以移动到下一行的相邻数字,也就是移动到下一行的相同序号处,或者下一行相同序号+1处。
方法一:不使用额外的空间,会更改数组。自下而上,从倒数第二行开始,倒数第二行的每一个元素j,都是下一行元素j和j+1的最小的一个加上本身的值。不断的更新,最终triangle[0][0]这个元素就是最小的路径和。
递推公式:triangle[i][j] += min(triangle[i+1][j],triangle[i+1][j+1]);
//方法一:不使用额外空间
class Solution {
public:
int minimumTotal(vector > &triangle) {
for(int i = triangle.size()-2; i >= 0; --i)
{
for(int j = 0;j < triangle[i].size();++j)
triangle[i][j] += min(triangle[i+1][j],triangle[i+1][j+1]);
}
return triangle[0][0];
}
};
方法二:O(n)的空间复杂度:将三角形最后一行的数据存入一个大小为n的vector中。从倒数第二行开始,使用递推公式不断的更新vector中的数据,最终更新完,vector中就只剩下了最小路径和。
class Solution{
public:
int minimumTotal(vector > &triangle) {
vector res(triangle.back());
for(int i = triangle.size()-2; i >= 0; --i){
for(int j = 0;j < triangle[i].size(); ++j){
res[j]=triangle[i][j]+min(res[j],res[j+1]);
}
}
return res[0];
}
}
方法三:使用递归:将三角形数组看成是一个二叉树,采用递归的方式。
class Solution {
public:
int minimumTotal(vector > &triangle)
{
if(triangle.empty())
return 0;
if(triangle.size() == 1 )
return triangle[0][0];
//后序遍历的思想:算出左子树的最小和,和右子树的最小和,根节点和其中较小的值相加。
int leftsum = minSumPath(triangle, 1, 0);
int rightsum = minSumPath(triangle, 1,1);
int minsum = triangle.at(0).at(0);
return (minsum + min(leftsum,rightsum));
}
int minSumPath(vector > &triangle,int row, int col)
{
if( row < triangle.size())
{
int left = minSumPath(triangle, row+1, col);
int right = minSumPath(triangle, row+1, col+1);
return triangle.at(row).at(col) + min(left,right);
}
return 0;
}
};
(*^▽^*)