题目要求:
给定一个数字三角形,找到从顶部到底部的最小路径和。每一步可以移动到下面一行的相邻数字上。
注意事项
如果你只用额外空间复杂度O(n)的条件下完成可以获得加分,其中n是数字三角形的总行数。
样例
比如,给出下列数字三角形:
[
[2],
[3,4],
[6,5,7],
[4,1,8,3]
]
从顶到底部的最小路径和为11 ( 2 + 3 + 5 + 1 = 11)。
思路:
上网看了动态规划的相关内容,学习了->动态规划(DP)之入门学习-数字三角形,但是觉得博主讲的不是很明白,不过看图片还是看懂了。
在这里再自己介绍一遍。
就题目样例的数字三角形来说,其实在数组里他是这样存在的:
[
[2],
[3,4],
[6,5,7],
[4,1,8,3]
]
所以从顶部到底部,每一步可以移动到相邻数字,对于triangle[i][j] 就是可以移动到他的正下方[i + 1][j] 或者右下方[i + 1][j + 1]。
动态规划的思想就是,在求解过程中用到子问题,保存子问题的解,减小时间复杂度。
从下往上遍历,从倒数第二行开始,将这一行的值改成它和倒数第一行中与他相邻的两个数字中较小的那个,与它本身相加的值。第一次遍历如下:
[
[2],
[3 ,4 ],
[7 ,6 ,10],
[4 ,1 ,8 ,3 ]
]
第二次遍历如下:
[
[2],
[9 ,10],
[7 ,6 ,10],
[4 ,1 ,8 ,3 ]
]
第三次遍历如下:
[
[11],
[9 ,10],
[7 ,6 ,10],
[4 ,1 ,8 ,3 ]
]
遍历到第一行结束,此时triangle[0][0]就是最小和。
代码:
class Solution {
public:
/*
* @param triangle: a list of lists of integers
* @return: An integer, minimum path sum
*/
int minimumTotal(vector<vector<int>> &triangle) {
// write your code here
int i, j;
for(i = triangle.size() - 2; i >= 0; i--){
for(j = 0; j < triangle[i].size(); j++){
triangle[i][j] += min(triangle[i+1][j], triangle[i+1][j+1]);
}
}
return triangle[0][0];
}
};