题目:
给定一个三角形,找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的结点上。
相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 + 1 的两个结点。
例如,给定三角形:
[ [2], [3,4], [6,5,7], [4,1,8,3] ]
自顶向下的最小路径和为 11
(即,2 + 3 + 5 + 1 = 11)。
解题思路:动态规划
1、最开始想的是dp[i] 表示到达第i行的最小路径和。后来一想,不对劲呀,最后一排的具体到每个数都是不同的路径,所以要用二维数组。dp[i][j] 就表示到达i行j列元素那个位置的最小路径和。
2、依题:dp[i][j] = dp[i-1][j] + triangle的[i][j]那个位置的值和dp[i-1][j-1]+triangle的[i][j]那个位置的值中的较小者。
3、写代码的时候会注意到两个细节:
①每一行的第一个数没有办法比较,只能由上一行的第一个数加过来。
②同样,每一行的最后一个数也没办法比较,因为i,j那个位置的上一行最多只能到i,j-1根本没有j
对于这两个位置的元素要特殊处理。
代码:
public static int minimumTotal(List<List<Integer>> triangle) {
int [][] dp = new int [triangle.size()][triangle.get(triangle.size()-1).size()];
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++) {
if (j ==0)
dp[i][j] = dp[i-1][j]+triangle.get(i).get(j);
else if (j == triangle.get(i).size()-1)
dp[i][j] = dp[i-1][j-1]+triangle.get(i).get(j);
else
dp[i][j] = Math.min(dp[i-1][j],dp[i-1][j-1])+triangle.get(i).get(j);
}
}
int res = Integer.MAX_VALUE;
int row = dp.length;
for (int i = 0; i < triangle.get(row-1).size(); i++) {
res = Math.min(res,dp[row-1][i]);
}
return res;
}