120. Triangle
题目
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.
解题思路
采用动态规划的方法。自底向上对每一行进行遍历,用minPathSum[i][j]
表示从最底层到达第i行的第j个元素的最小路径和。初始时i = trianglel.size()-1; minPathSum[i][j] = triangle[i][j];
,注意到上一层第j个元素的最小路径和等于下一层的第j个和第j+1元素的最小路径和中较小的一个加上当前元素的值,因此,状态转移方程为minPathSum[i][j] = min(minPathSum[i+1][j], minPathSum[i+1][j+1]) + triangle[i][j];
。最终我们遍历到顶层,得到minPathSum[0][0]
就是从最底层到顶层的最小路径和,即从最顶层到底层的最小路径和。注意到minPathSum其实只用使用长度为n(n为行数)的一维数组,因为我们从下至上,从左至右计算,将计算出的结果继续储存在minPathSum一维数组中不会影响结果,空间复杂度为
O
(
n
)
O(n)
O(n)。由于要计算所有元素的minPathSum且计算每个元素的minPathSum的时间复杂度为常数,因此时间复杂度为
O
(
n
2
)
O(n^2)
O(n2)。
代码如下:
class Solution {
public:
int minimumTotal(vector<vector<int>>& triangle) {
if (triangle.size() == 0) return 0;
vector<int> minPathSum = triangle[triangle.size()-1];
for (int i = triangle.size() - 2; i >= 0; i--) {
for (int j = 0; j < i + 1; j++) {
minPathSum[j] = min(minPathSum[j], minPathSum[j+1]) + triangle[i][j];
}
}
return minPathSum[0];
}
};