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
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.
这道题和前面求矩阵中的最短路径很相似,但是它要求在O(n)的空间复杂度内求解问题,前面矩阵中的最短路径中的解法二就是在O(n)空间复杂度内求解的,这里可以借鉴一下。
分析:
设A[i][j]表示到triangle[i][j]的最短路径,那么
- if j==0 : A[i][j]=A[i-1][j]+triangle[i][j]
- else if j==width-1 : A[i][j]=A[i-1][j-1]+triangle[i][j]
- else A[i][j]=min{A[i-1][j-1],A[i-1][j]}+triangle[i][j]
由于A[i][j]只与A[i-1][j-1]和A[i-1][j]有关,那么可以只保留这两行的数据,解法一就是使用preRow保留i-1行的数据,curRow保留当前行的数据。
时间复杂度O(N^2),空间复杂度O(N)。
runtime:8ms
解法一:
class Solution {
public:
int minimumTotal(vector<vector<int>>& triangle) {
int height=triangle.size();
vector<int> curRow(height,0);
vector<int> preRow(height,0);
for(int i=0;i<height;i++)
{
int width=triangle[i].size();
for(int j=0;j<width;j++)
{
if(j==0)
curRow[0]=preRow[0]+triangle[i][j];
else if(j==width-1)
curRow[j]=preRow[j-1]+triangle[i][j];
else
curRow[j]=min(preRow[j-1],preRow[j])+triangle[i][j];
}
preRow=curRow;
}
int ans=INT_MAX;
for(int i=0;i<height;i++)
{
ans=min(ans,curRow[i]);
}
return ans;
}
};
解法二:
注意到preRow的使用方式,可以进一步优化,如果对j进行从右到左遍历,那么可以只用一个数组来保存数据。
class Solution {
public:
int minimumTotal(vector<vector<int>>& triangle) {
int height=triangle.size();
vector<int> curRow(height,0);
for(int i=0;i<height;i++)
{
int width=triangle[i].size();
for(int j=width-1;j>=0;j--)
{
if(j==0)
curRow[0]+=triangle[i][j];
else if(j==width-1)
curRow[j]=curRow[j-1]+triangle[i][j];
else
curRow[j]=min(curRow[j-1],curRow[j])+triangle[i][j];
}
}
int ans=INT_MAX;
for(int i=0;i<height;i++)
{
ans=min(ans,curRow[i]);
}
return ans;
}
};