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
[ [2], [3,4], [6,5,7], [4,1,8,3] ]
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)复杂度的算法来解决此问题。第一种方法比较好想一点,就是从头到尾解决这个问题,从第二层的数据开始遍历整个三角形数据,走到每一个点有两种情况,如果这个点是边界(左右边界都包括),那么走到这个点的代价就是与边界点相邻的上一层的点对应的代价加上这个边界点对应的值。如果这个点不是边界,那么走到这个点的代价就是走到左上方的点的代价和走到右上方的点的代价最小的那个代价加上这个点对应的值。
代码如下:
class Solution {
public:
int minimumTotal(vector<vector<int>>& triangle) {
int n = triangle.size();
for (int i = 1; i < n; ++i) {
for (int j = 0; j < triangle[i].size(); ++j) {
if (j == 0) triangle[i][j] += triangle[i - 1][j];
else if (j == triangle[i].size() - 1) triangle[i][j] += triangle[i - 1][j - 1];
else {
triangle[i][j] += min(triangle[i - 1][j - 1], triangle[i - 1][j]);
}
}
}
int res = triangle[n - 1][0];
for (int i = 0; i < triangle[n - 1].size(); ++i) {
res = min(res, triangle[n - 1][i]);
}
return res;
}
};
第二种方法是我在网上找到的,我觉得思路很好,拿出来介绍一下:
这种方法是从最底层即数据最多的那一层开始解决问题,先申请一个大小为n的min数组(n的值即为最底层的数据个数或者说是三角形数据的层数),此数组最初存储的就是最底层的数据。然后向上遍历,每次只需要修改min数组的值即可,遍历到最顶层的时候,min[0]的值就是最后的答案,这种方法不需要修改题目中传入的二维向量triangle,要比上一个方法好一些。
class Solution {
public:
/** 计算三角从上至小最小路径和 */
int minimumTotal(vector<vector<int> > &triangle) {
vector<int> minNums = triangle[triangle.size() - 1];
for (int i = triangle.size() - 2; i > - 1; --i)
for (int j = 0; j <= i; ++j)
minNums[j] = (minNums[j] < minNums[j + 1] ? minNums[j] : minNums[j + 1])
+ triangle[i][j];
return minNums[0];
}
};