动态规划,最后路径和最小,那么每一步必须最小
一、求解
求出到达最后一层的所有最小路径,然后再求出其中最小的即可。
初始化二维数组用来存放结果
final int size = triangle.get(triangle.size() - 1).size();
int[][] result = new int[size][size];
result[0][0] = triangle.get(0).get(0);
状态转移方程
其中的length对应三角形中每一行的路径长度。
填表
0 | 1 | 2 | 3 | |
---|---|---|---|---|
0 | 2 | |||
1 | 5 | 6 | ||
2 | 11 | 10 | 13 | |
3 | 15 | 11 | 18 | 16 |
代码
public static int minimumTotal(List<List<Integer>> triangle) {
final int size = triangle.get(triangle.size() - 1).size();
int[][] result = new int[size][size];
result[0][0] = triangle.get(0).get(0);
if (size == 1){
return result[0][0];
}
int min = Integer.MAX_VALUE;
for (int i = 1; i < size; i++){
for (int j = 0; j < triangle.get(i).size(); j++) {
if (j - 1 >= 0){
if (j == triangle.get(i).size() - 1){
result[i][j] = result[i-1][j-1] + triangle.get(i).get(j);
}else {
result[i][j] = Math.min(result[i -1][j - 1] + triangle.get(i).get(j), result[i -1][j] + triangle.get(i).get(j));
}
}else {
result[i][j] = result[i - 1][j] + triangle.get(i).get(j);
}
if (i == size - 1){
min = Math.min(min, result[i][j]);
}
}
}
return min;
}
二、优化
根据上边的转移方程以及填表的过程,要想保存前一个转移状态的话,那么只能倒着来计算最短路径,因为计算当前状态的值要用到前一状态,如果从上往下计算的话,前一天状态就会被覆盖。
初始状态
0 | 1 | 2 | 3 |
---|---|---|---|
4 | 1 | 8 | 3 |
填表
扫描倒数第二行:
0 | 1 | 2 | 3 |
---|---|---|---|
7 | 6 | 10 | 3 |
扫描倒数第三行:
0 | 1 | 2 | 3 |
---|---|---|---|
9 | 10 | 10 | 3 |
扫描倒数第四行:
0 | 1 | 2 | 3 |
---|---|---|---|
11 | 10 | 10 | 3 |
代码
public static int minimumTotal(List<List<Integer>> triangle) {
final int size = triangle.get(triangle.size() - 1).size();
int[] result = new int[size];
for (int i = 0; i < size; i++) {
result[i] = triangle.get(triangle.size() - 1).get(i);
}
int length = triangle.size() - 2;
for (int i = length; i >= 0; i--) {
for (int j = 0; j < triangle.get(i).size(); j++) {
result[j] = Math.min(triangle.get(i).get(j)+result[j], triangle.get(i).get(j)+result[j + 1]);
}
}
return result[0];
}