给定一个三角形,找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的结点上。
例如,给定三角形:
[
[2],
[3,4],
[6,5,7],
[4,1,8,3]
]
自顶向下的最小路径和为 11
(即,2 + 3 + 5 + 1 = 11)。
说明:
如果你可以只使用 O(n) 的额外空间(n 为三角形的总行数)来解决这个问题,那么你的算法会很加分。
解题思路:典型的动态规划问题,把三角形看作是二维数组的左下半部分,那么问题就变成求解转移矩阵最下面一排的最小值,具体来说,左下列只需要用本数值+上方数值,对角线只需要用本数值+左上方数值,中间的部分则是用 本数值+上方数值、本数值+左上方数值中的最小值,依次递推。
public static int minimumTotal(List<List<Integer>> triangle) {
/* 三角形:
* 2 0 0 0
* 3 4 0 0
* 6 5 7 0
* 4 1 8 3
* 可以生成的最小路径是:
* 2 0 0 0
* 5 6 0 0
* 11 10 13 0
* 15 11 18 16
* 也就是说,每一个点的最小路径,是当前点的值加 [正上] [左上] 的值 的最小值
* */
/*
* -1 0
* -2 -3
* */
int result = 0;
int length = triangle.size();
//如果数组为空,直接返回0
if(length==0){
return 0;
}
//定义二维数组存放三角形
int [][]a = new int[length][length];
for(int i=0;i<length;i++){
for(int j=0;j<=i;j++){//对二维数组的左下侧赋值
a[i][j] = triangle.get(i).get(j);
}
}
//输出初始数组
// for(int i=0;i<length;i++){
// for(int j=0;j<length;j++){
// System.out.printf(a[i][j]+" ");
// }
// System.out.println();
// }
// System.out.println();
//对二维数组进行转移操作
//首先左下是依次累加的
for(int i=1;i<length;i++){
a[i][0] = a[i][0] + a[i-1][0];
}
//其次对角线也是依次累加的
for(int i=1;i<length;i++){
a[i][i] = a[i][i] + a[i-1][i-1];
// System.out.println(a[i][i]+"");
}
//然后中间的一小部分(左列和对角线之间的部分),从左上角开始往右下角推,每个数字是其本身与 [上方]/[左上]相加结果中的最小值
for(int i=1;i<length;i++){
for(int j=1;j<i;j++){
a[i][j] = Math.min( (a[i-1][j-1]+a[i][j]) , (a[i-1][j]+a[i][j]) );
}
}
//输出转移后的数组
// for(int i=0;i<length;i++){
// for(int j=0;j<length;j++){
// System.out.printf(a[i][j]+" ");
// }
// System.out.println("");
// }
//结果是最后一行的最小值
result = a[length-1][0];
for(int j=0;j<length;j++){
if(a[length-1][j] < result){
result = a[length-1][j];
}
}
return result;
}
public static void main(String[] args) {
List<Integer> a1 = new ArrayList<Integer>();
List<Integer> a2 = new ArrayList<Integer>();
List<Integer> a3 = new ArrayList<Integer>();
List<Integer> a4 = new ArrayList<Integer>();
a1.add(-1);
a2.add(-2);a2.add(-3);
// a1.add(2);
// a2.add(3);a2.add(4);
// a3.add(6);a3.add(5);a3.add(7);
// a4.add(4);a4.add(1);a4.add(8);a4.add(3);
List<List<Integer>>a = new ArrayList<List<Integer>>();;
a.add(a1);
a.add(a2);
// a.add(a3);
// a.add(a4);
System.out.println(minimumTotal(a));
}