题目简介:
给定一个三角形,找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的结点上。
相邻的结点 在这里指的是 下标
与 上一层结点下标
相同或者等于 上一层结点下标 + 1
的两个结点。
例如,给定三角形:
1 2 3 4 5 6
| [ [2], [3,4], [6,5,7], [4,1,8,3] ]
|
自顶向下的最小路径和为 11
(即,2 + 3 + 5 + 1 = 11)。
思路:
动态规划,dp[i][j]
代表从起点开始走到(i, j)
点的最小路径和。
首先初始化第一列和最后一列(处理边界问题)。
由于(i, j)
只能从(i - 1, j)
和(i - 1, j - 1)
两个点走过来,所以dp[i][j] = min(dp[i - 1][j - 1], dp[i - 1][j]) + triangle[i][j]
。
最后返回三角形最后一行dp
值中最小的值即可。
tip:
- 需要注意的是计算
triangle[i][j]
这个点的dp
时,可能会不存在triangle[i - 1][j]
这个点,从而不存在dp[i - 1][j]
,所以需要初始化最后一列。
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| class Solution { public: int minimumTotal(vector<vector<int>>& triangle) {
vector<vector<int>> dp(triangle.size(), vector<int>(triangle.size(), 0));
dp[0][0] = triangle[0][0];
for(int i = 1; i < triangle.size(); i++){
dp[i][0] = dp[i - 1][0] + triangle[i][0]; dp[i][triangle[i].size() - 1] = dp[i - 1][triangle[i - 1].size() - 1] + triangle[i][triangle[i].size() - 1]; }
for(int i = 1; i < triangle.size(); i++){
for(int j = 1; j < i; j++){
dp[i][j] = min(dp[i - 1][j - 1], dp[i - 1][j]) + triangle[i][j]; } }
int res = INT_MAX; for(int i = 0; i < triangle[triangle.size() - 1].size(); i++){
res = min(res, dp[triangle.size() - 1][i]); } return res; } };
|