题意:给出一个三角形,求出从顶到底的最小路径和,路径中每个节点必须是相邻的。描述起来比较费劲,见题目中的示例如下:
例如,给出下面这个三角形
[
[2],
[3,4],
[6,5,7],
[4,1,8,3]
]
从顶到底的最小路径和为11 (路径为 2 + 3 + 5 + 1 = 11).
分析:刚开始拿到题目,想到的是贪心算法,一路向下走,但是这种方法只能是局部最小的,而不是全局最小的。于是又想到了从下向上走,但是无论方向如何,一条路线上求出来的和一定是局部最小,而不是全局的。
所以怎样求得全局最小和,成了一个关键的问题,可以想象,最终的结果一定是从第一行到最后一行,例如示例中的结果路径有2->4、2->1、2->8、2->3。找到这四条路径里每一条的最小和很简单(就是贪心算法所求得的局部和),则全局的最小和一定是这四条最小和里最小的那个,因此我们只需要分配一个N个元素的数组,用来存储这N个局部最小和即可。这样也达到了Note中提到的使用O(n)的额外空间。
我选用的遍历方式为从下向上,公式为:
f[j]=f[j]<f[j+1]?f[j]:f[+1];
f[j]+=triangle[i][j]
其中,i表示当前的行数,j表示当前的列数。
于是得到如下的代码:
class Solution {
public:
int minimumTotal(vector<vector<int> > &triangle) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
vector<int> f(triangle.size());
std::copy(triangle[triangle.size()-1].begin(), triangle[triangle.size()-1].end(), f.begin());
for (int i = triangle.size()-2; i >= 0; --i)
{
for (int j = 0; j < triangle[i].size(); j ++)
{
f[j] = (f[j] < f[j+1] ? f[j] : f[j+1]) + triangle[i][j];
}
}
return f[0];
}
};