1.题目
给定一个三角形,找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的结点上。
例如,给定三角形:
[
[2],
[3,4],
[6,5,7],
[4,1,8,3]
]
自顶向下的最小路径和为 11(即,2 + 3 + 5 + 1 = 11)。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/triangle
2.想法
可将等腰三角形看成直角三角形即所有元素向左对齐,
利用动态规划算出每个位置的最小路径和,边界情况在最左边只能从上走到下,只需将上面的加上本格即可;最右边只能由上面往右下走,只需将左上的上面加上本格即可。普通情况本格加上上面与左上上面的最小值。最终将最后一行数组排序,找到最小值。
3.题解
class Solution {
public int minimumTotal(List<List<Integer>> triangle) {
int m=triangle.size();
int [][]dp=new int[m][m];
dp[0][0]=triangle.get(0).get(0);
for(int i=1;i<triangle.size();i++){
for(int j=0;j<triangle.get(i).size();j++){
int temp=triangle.get(i).get(j);
if(j==0)dp[i][j]=temp+dp[i-1][j];
else if(j==triangle.get(i).size()-1){dp[i][j]=temp+dp[i-1][j-1];}
else{
dp[i][j]=temp+Math.min(dp[i-1][j],dp[i-1][j-1]);
}
//System.out.println(dp[i][j]);
}
}
Arrays.sort(dp[m-1]);
return dp[m-1][0];
}
}
空间优化
class Solution{
public int minimumTotal(List<List<Integer>> triangle) {
int[] dp = new int[triangle.size()];
int ans = 0;
dp[0] = triangle.get(0).get(0);
int temp,prev = 0,cur;// prev为上一行的dp[j-1],cur为上一行的dp[j]
for (int i = 1; i < triangle.size(); i++) {
for (int j = 0; j < triangle.get(i).size(); j++) {
temp = triangle.get(i).get(j);
cur = dp[j];
if (j == 0) dp[j] = cur + temp;
else if (j == triangle.get(i).size() -1) dp[j] = prev+temp;
else dp[j] = Math.min(prev,cur) + temp;
prev = cur;
}
}
for (int i = 1; i < dp.length; i++) {
if (dp[ans] > dp[i]) ans = i;
}
return dp[ans];
}
}
4.效率
开二维数组,效率不是很好
开一维数组,好像也差不了多少