题目介绍
在一个三角形中,找到从上到下的最短路径的长度。每次移动只能从它上面行的相邻因素移动到下面行的元素。例如如下的三角形,从上到下的最短路径为2+3+5+1=11。
[2]
[3,4]
[6,5,7]
[4,1,8,3]
解题思路
- 动态规划:O(mn)空间复杂度
- i,j表示三角形的行数和列数,dp[i][j]表示从顶部到第i行,第
j 列路径值。 - i=0,dp[0][0]=triangle[0][0]
- 1<i<=triangle.size()−1,1=<j<=triangle[i].size()−2,dp[i][j]=min(dp[i−1][j−1],dp[i−1][j])+triangle[i][j],
- 这种算法的空间复杂度为O(mn),因为每行信息都需要记录在dp[i][j]中
- i,j表示三角形的行数和列数,dp[i][j]表示从顶部到第i行,第
- 动态规划:O(n)空间复杂度
- 在每次计算dp中的第j列的信息时从后向前计算,就可以用O(n)的空间复杂度了,因为计算第i行的距离时只和第i-1行的信息有关系,与前面的其它行是没有关系的。
代码
O(mn) 空间复杂度的代码
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<vector>
using namespace std;
int minmumTotal(vector<vector<int> >& triangle)
{
vector<vector<int> > mark;
mark.push_back(triangle[0]);
for(int i = 1; i < triangle.size(); i++)
{
vector<int> t;
vector<int> tmp = triangle[i];
t.push_back(mark[i - 1][0] + tmp[0]);
for(int j = 1; j < tmp.size() - 1; j++)
{
t.push_back((mark[i - 1][j - 1] > mark[i - 1][j] ? mark[i - 1][j] : mark[i - 1][j - 1]) + tmp[j]);
}
t.push_back(mark[i - 1][tmp.size() - 2] + tmp[tmp.size() - 1]);
mark.push_back(t);
}
vector<int> r = mark[mark.size() - 1];
int min = 1000000;
for(int i = 0; i < r.size(); i++)
if(r[i] < min)
min = r[i];
return min;
}
int main(int argc, char** argv)
{
int i1[1] = {2};
int i2[2] = {3, 4};
int i3[3] = {6, 5, 7};
int i4[4] = {4, 1, 8, 3};
vector<int> r1(i1, i1 + 1);
vector<int> r2(i2, i2 + 2);
vector<int> r3(i3, i3 + 3);
vector<int> r4(i4, i4 + 4);
vector<vector<int> > triangle;
triangle.push_back(r1); triangle.push_back(r2); triangle.push_back(r3); triangle.push_back(r4);
int r = minmumTotal(triangle);
printf("min path = %d\n", r);
return 0;
}
- O(n)空间复杂度的代码
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<vector>
using namespace std;
int minmumTotal_Update(vector<vector<int> >& triangle)
{
vector<int> mark(triangle[triangle.size() - 1].size(), 0);
mark[0] = triangle[0][0];
printf("%d\n", mark[0]);
for(int i = 1; i < triangle.size(); i++)
{
vector<int> tmp = triangle[i];
for(int j = tmp.size() - 1; j >= 0; j--)
{
if(j == tmp.size() - 1)
mark[j] = mark[j - 1] + triangle[i][j];
else if(j == 0)
mark[j] += triangle[i][j];
else
{
int m = mark[j - 1] > mark[j] ? mark[j] : mark[j - 1];
mark[j] = m + triangle[i][j];
}
printf("%d ", mark[j]);
}
printf("\n");
}
int min = 1000000;
for(int i = 0; i < mark.size(); i++)
if(mark[i] < min)
min = mark[i];
return min;
}
int main(int argc, char** argv)
{
int i1[1] = {2};
int i2[2] = {3, 4};
int i3[3] = {6, 5, 7};
int i4[4] = {4, 1, 8, 3};
vector<int> r1(i1, i1 + 1);
vector<int> r2(i2, i2 + 2);
vector<int> r3(i3, i3 + 3);
vector<int> r4(i4, i4 + 4);
vector<vector<int> > triangle;
triangle.push_back(r1); triangle.push_back(r2); triangle.push_back(r3); triangle.push_back(r4);
int r = minmumTotal_Update(triangle);
printf("min path = %d\n", r);
return 0;
}