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.
Hide Tags Array Dynamic Programming
分析:
动态规划,重点就是找递推公式。。。
只需要从上到下,从左到右,计算出每个元素的最小路径和,然后再找出最后一行中的最小值即可。
由于题目要求只用O(n)空间复杂度,那么可以直接修改原二维数组,每遍历一个元素,将其更新为最小路径和即可,最后一行的时候,同时更新最终的最小路径和。
需要注意的地方,每一行的首元素和末尾元素只有一个相邻的元素,需分开处理。
对于第[i][j]个元素(第i行第j列元素,i > 0):
若是行首元素,那么tri[i][j] += tri[i-1][j]
若是行尾元素,那么tri[i][j] += tri[i-1][j-1]
若是中间元素,那么 tri[i][j] += min(tri[i-1][j-1],tri[i-1][j])
此时若是最后一行,在更新每个元素对应的最小路径和之后,更新全局的最小路径和minSum。(也可以在所有计算完成之后,再去找最后一行的最小值,效率一样)
以下是C++实现代码:
/*/////////////////8ms//*/
class Solution {
public:
int min(int a, int b){
return a < b? a:b;
}
int minimumTotal(vector<vector<int> > &tri) {
int n = tri.size();
if(n == 0) // 若数组为空,则返回0
return 0;
if(n == 1) // 只有一行,那么只有一个元素,返回即可
return tri[0][0];
int minSum = INT_MAX; //全局最小路径和
for(int i = 1; i < n; i++){ //从第1行开始,计算每个元素对应的最小路径和,并更新到本身的位置
int m = tri[i].size(); //程序执行到此处,表示m必然大于0
for(int j = 0; j < m; j++){ //处理第i行的所有元素
if(j == 0) //更新行首元素的最小路径和
tri[i][j] += tri[i-1][j];
else if(j == m-1) //更新行尾元素的最小路径和
tri[i][j] += tri[i-1][j-1];
else{ //非行首尾的元素则利用递推公式进行计算
tri[i][j] += min(tri[i-1][j-1],tri[i-1][j]);
}
if(i == n-1){ // 利用最后一行的最小路径和更新minSum
if(tri[i][j] < minSum)
minSum = tri[i][j];
}
}
}
return minSum;
}
};