难度:中等
给定一个三角形,找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的结点上。
相邻的结点 在这里指的是 下标
与 上一层结点下标
相同或者等于 上一层结点下标 + 1
的两个结点。
例如,给定三角形:
[ [2], [3,4], [6,5,7], [4,1,8,3] ]
自顶向下的最小路径和为 11
(即,2 + 3 + 5 + 1 = 11)。
说明:
如果你可以只使用 O(n) 的额外空间(n 为三角形的总行数)来解决这个问题,那么你的算法会很加分。
题目分析:
显然是DP问题。前面两题杨辉三角在某种程度上也是作为此题的铺垫。根据观察可得出状态转换方程
1.状态转换方程:f[i][j] = min(f[i-1][j-1], f[i-1][j]) + arr[i][j]
2.使用二维数组作为数据结构
3.初始化,f[0][0] = arr[0][0]
4.注意事项:我们把arr二维数组向左靠齐,j只能访问0~i-1
1)当j为0的时候,是不能访问i-1的,状态方程变成了f[i][j] = f[i-1][0]) + arr[i][j]
2)当j == i 的时候,状态转换方程变成了f[i][j] = f[i-1][j]) + arr[i][j]
参考代码:
class Solution {
public:
int minimumTotal(vector<vector<int>>& triangle) {
if(triangle.empty())
return 0;
//申明最小值,因为最后一行需要找到最小路径,这里变量名不能设置为min,与函数min冲突
int my_min = INT_MAX;
//状态转换方程
vector<vector<int>> f(triangle.size(),vector<int>(triangle.size(),0));
f[0][0] = triangle[0][0];
for(int i = 1; i < triangle.size(); i++)
{
//左边第一列是不能访问j-1的
f[i][0] = f[i-1][0] + triangle[i][0];
for(int j = 1; j < i; j++)
{
f[i][j] = min(f[i-1][j-1],f[i-1][j])+triangle[i][j];
}
//右边最后一个位置是不能访问i的
f[i][i] = f[i-1][i-1] + triangle[i][i];
}
//在最后一行中找出最小值
for(int i = 0; i < triangle[triangle.size()-1].size(); i++)
{
if(f[triangle.size()-1][i] < my_min)
my_min = f[triangle.size()-1][i];
}
return my_min;
}
};