package leetcode;
/*Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below.
For example, given the following triangle
[
[2],
[3,4],
[6,5,7],
[4,1,8,3]
]
The minimum path sum from top to bottom is11(i.e., 2 + 3 + 5 + 1 = 11).
Note:
Bonus point if you are able to do this using only O(n) extra space, where n is the total number of rows in the triangle.*/
import java.util.ArrayList;
public class Triangle {
public static void main(String[] args) {
}
public int minimumTotal(ArrayList<ArrayList<Integer>> triangle) {
//方法1:三角形从上到下的方法,不断用求和之后的值不断替代下一层的值,最后通过循环比较最小一层的元素中谁最小,谁就是最终的结果
//这种方法我原创的弱点是没有充分利用Math这个类,竟然还用数学的方法比较两个值的大小,浪费了时间和空间
int N = triangle.size();
if(N == 1)
return triangle.get(0).get(0);
for(int i = 1 ; i < N ; i ++) {
for(int j = 0 ; j < triangle.get(i).size() ; j ++) {
if(j == 0) {
int element1 = triangle.get(i).get(j)+triangle.get(i-1).get(j); //是这一层的头元素,只能和上一层的头元素形成路径
triangle.get(i).set(j, element1);
}else if(j == triangle.get(i).size()-1) {
int element2 = triangle.get(i).get(j)+triangle.get(i-1).get(j-1); //中间的元素可以和上一层的同位置的元素和前一个位置的元素形成路径
triangle.get(i).set(j, element2);
}else {
int element3 = triangle.get(i).get(j)+triangle.get(i-1).get(j-1); //这一次的尾元素,只能和上一层的尾元素形成路径
int element4 = triangle.get(i).get(j)+triangle.get(i-1).get(j);
int element = element3 < element4 ? element3 : element4;
triangle.get(i).set(j, element);
}
}
}
int min = Integer.MAX_VALUE;
for(int j = 0 ; j < triangle.get(N-1).size() ; j ++) {
if(triangle.get(N-1).get(j) < min) {
min = triangle.get(N-1).get(j);
}
}
return min;
//方法2:采用从小到上的方法,外层循环从倒数第2层开始,不是从最后一层开始,逐步用结果替代上一层的元素
//方法2是leetcode的最好的解法,层数较少,最棒的地方是程序非常简便简洁
/*for(int i = triangle.size() - 2 ; i >= 0 ; i --) {
for(int j = 0 ; j < triangle.get(i+1).size() - 1; j ++) { //因为用到了j+1,所以没有循环到末尾,省的了判断
int min = Math.min(triangle.get(i + 1).get(j), triangle.get(i + 1).get(j + 1));
triangle.get(i).set(j, min+triangle.get(i).get(j));
}
}
return triangle.get(0).get(0);*/
}
}