1.题目描述
给定一个三角形,找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的结点上。
例如,给定三角形:
[
[2],
[3,4],
[6,5,7],
[4,1,8,3]
]
自顶向下的最小路径和为 11(即,2 + 3 + 5 + 1 = 11)。
2.解题思路
动态规划:
每一层的值加上上一层的值中最小值,最后取最后一层的最小值就好了
例如
[2] [2] [3,4] 变成 [5,6] [6,5,7] [11,10,13] [4,1,8,3] [15,11,18,16]
- 动态规划初始化:dp[i][j]代表从第一层到达[i][j]的最小路径和
- 第一层:就是
- dp[0][0] = triangle.get(0).get(0);
- 第二层: 就是
- dp[1][0] = dp[0][0] + triangle.get(1).get(0),
dp[1][1] = dp[0][0] + triangle.get(1).get(1)- 动态规划转移状态矩阵:
- dp[i][j] = triangle.get(i).get(j) + dp[i-1][j-1]; 【i == j时,即到达矩阵边界,只能选择上一层的最后一个数的路径】
- dp[i][j] = triangle.get(i).get(j)+ Math.min(dp[i-1][j-1],dp[i-1][j]);【选择上一层相邻两个路径中较小的那个路径+ 当前值】
3.代码
class Solution {
public static int minimumTotal(List<List<Integer>> triangle) {
if(triangle.size() == 0)
return 0;
if(triangle.size() == 1)
return triangle.get(0).get(0);
int len = triangle.get(triangle.size()-1).size();
int dp[][] = new int[len][len];
//初始化第一层跟第二层
dp[0][0] = triangle.get(0).get(0);
dp[1][0] = dp[0][0]+triangle.get(1).get(0);
dp[1][1] = dp[0][0] + triangle.get(1).get(1);
//第一列初始化
for(int i = 2;i < len;i++){
dp[i][0] = dp[i-1][0] + triangle.get(i).get(0);
}
for(int i = 2;i<len;i++){
for(int j = 1;j<= i ;j++){
//最后一个数的dp,因为上一层比下一层少一个,所以只能最后一个数只能加上上一层的最后一个dp
if(j == i){
dp[i][j] = triangle.get(i).get(j) + dp[i-1][j-1];
}else{
dp[i][j] = triangle.get(i).get(j)+ Math.min(dp[i-1][j-1],dp[i-1][j]);
}
}
}
//三角形最后一层中的最小值就是最小路径
int res = dp[len-1][0];
for(int i = 1;i<len;i++){
if(dp[len-1][i] < res){
res = dp[len-1][i];
}
}
return res;
}
}