1.问题描述
给定一个三角形,找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的结点上。
例如,给定三角形:
[
[2],
[3,4],
[6,5,7],
[4,1,8,3]
]
自顶向下的最小路径和为11(即2+3+5+1=11)。
2.问题解决
用 D( i, j ) 表示第 i 行第 j 个元素到最上方元素(例子中为2)的最小距离,同时用a( i, j )表示第i行第j个元素的路径长。
(1)自顶向下考虑
一般情况下,D( i, j ) = min { D( i - 1, j ) , D( i - 1, j - 1) } + a( i, j )。最后在最后一行中找到最小的值。
(2)自底向上考虑
一般情况下,D( i, j ) = min { D( i + 1, j ) , D( i + 1, j + 1) } + a( i, j )。最后得到的第一行的唯一一个元素即为答案。
3.代码实现
(1)自顶向下
int minimumTotal(vector<vector<int>>& triangle)
{
int len=triangle.size();
vector<vector<int>> count(len);//count[i][j]保存从开始元素到第i行第j列的最短路径长度
count[0].push_back(triangle[0][0]);//初始化count数组
for(int i=1;i<len;i++)
{
for(int j=0;j<triangle[i].size();j++)
{
if(j==0)
//当j=0时为最左边元素,上一行中不存在第二维下标为j-1的元素
count[i].push_back(count[i-1][j]+triangle[i][j]);
else if(j==triangle[i].size()-1)
//当j=reiangle[i].size()-1时为最右边元素,上一行中不存在第二维下标为j的元素
count[i].push_back(count[i-1][j-1]+triangle[i][j]);
else//一般情况
count[i].push_back(min(count[i-1][j],count[i-1][j-1])+reiangle[i][j]);
}
}
int min=count[len-1][0];
for(int i=1;i<count[len-1].size();i++)//遍历count的最后一行元素找最小值
if(count[len-1][i]<min)
min=count[len-1][i];//更新min
return min;
}
(2)自底向上
int minimumTotal(vector<vector<int>>& triangle)
{
int len=triangle.size();
vector<vector<int>> count(len);
for(int i=0;i<triangle[len-1].size();i++)//初始化count数组
count[len-1].push_back(triangle[len-1][i]);
for(int i=len-2;i>=0;i--)
{
for(int j=0;j<triangle[i].size();j++)//不存在像自顶向下处理时的特殊情况
count[i].push_back(min(count[i+1][j],count[i+1][j+1])+triangle[i][j]);
}
return count[0][0];
}