题目链接 => 戳这里

题目解析
这道题其实有一点是需要另外拿出来讲的,对比跑楼梯,跑楼梯的最后状态求解,我们是很明确要求解的节点的,但是这道题,如果我们自顶向下求解的话,我们会发现我们并不是很明确究竟最后要返回dp[i][j]中的哪个节点,当然也可以做到,因为我们知道最后的解一定是在最后一行中的某个数,所以我们只需要对最后一行的dp值进行排序,然后返回最小的值即可。但是我们自底向上的话,最终的求解节点就明确是dp[0][0]了;
动态规划四步走:
1.问题拆解:
关键条件是每一步只能移动到下一行的相邻节点,也就是说经过dp[i][j]的节点,只可能经过dp[i+1][j]或者dp[i+1][j+1],那也就是说对dp[i][j]的最小值求解就拆解成了对dp[i+1][j]和dp[i+1][j+1]中的最小值加上[i][j]节点本身的值了;
2.状态定义:
节点[i][j]的路径最小值 = Min(dp[i+1][j],dp[i+1][j+1]) + 节点[i][j]本身的值;
3.递推方程:
dp[i][j] = Math.Min(dp[i+1][j], dp[i+1][j+1]) + triangle[i][j];
4.实现:
状态值初始化:最后一行的数据需要自行初始化
解法
class Solution {
public int minimumTotal(List<List<Integer>> triangle) {
int size = triangle.size();
// 基本操作:声明状态方程数组
int[][] dp = new int[size][size];
// 状态值初始化
List<Integer> lastRow = triangle.get(size-1);
for (int i = 0; i < lastRow.size(); i++) {
dp[size-1][i] = lastRow.get(i);
}
for (int i = size - 2; i >= 0; i--) {
List<Integer> tmp = triangle.get(i);
for (int j = 0; j < i+1; j++) {
dp[i][j] = Math.min(dp[i+1][j], dp[i+1][j+1]) + tmp.get(j);
}
}
return dp[0][0];
}
}
网友评论