题目
方法一:动态规划
public class MinimumTotal {
public int minimumTotal(List<List<Integer>> triangle) {
//动态规划,自上而下求出每一步的最小路径。
int h = triangle.size();
int[][] arr = new int[h][triangle.get(h-1).size()];
arr[0][0] = triangle.get(0).get(0);
for (int i = 1; i < h; i++) {
List<Integer> l = triangle.get(i);
for (int j = 0; j < l.size(); j++) {
if (j == 0) {
arr[i][j] = arr[i-1][j] + l.get(j);
} else if (j == (l.size()-1)){
arr[i][j] = arr[i-1][j-1] + l.get(j);
} else {
arr[i][j] = Math.min(arr[i-1][j], arr[i-1][j-1]) + l.get(j);
}
}
}
int min = arr[h-1][0];
for (int i = 1; i < triangle.get(h-1).size(); i++) {
min = Math.min(min, arr[h-1][i]);
}
return min;
}
public static void main(String[] args) {
MinimumTotal minimumTotal = new MinimumTotal();
List<List<Integer>> triangle = new ArrayList<List<Integer>>();
List<Integer> l = getList(new int[]{2});
triangle.add(l);
l = getList(new int[]{3,4});
triangle.add(l);
l = getList(new int[]{6,5,7});
triangle.add(l);
l = getList(new int[]{4,1,8,3});
triangle.add(l);
/*List<Integer> l = getList(new int[]{-10});
triangle.add(l);*/
System.out.println(minimumTotal.minimumTotal(triangle));
}
public static List<Integer> getList(int[] k) {
List<Integer> l = new ArrayList<Integer>();
for (int i = 0; i < k.length; i++) {
l.add(k[i]);
}
return l;
}
}
方法二:动态规划(空间复杂度改进)
public class MinimumTotal {
public static void main(String[] args) {
MinimumTotal minimumTotal = new MinimumTotal();
List<List<Integer>> triangle = new ArrayList<List<Integer>>();
List<Integer> l = getList(new int[]{2});
triangle.add(l);
l = getList(new int[]{3,4});
triangle.add(l);
l = getList(new int[]{6,5,7});
triangle.add(l);
l = getList(new int[]{4,1,8,3});
triangle.add(l);
/*List<Integer> l = getList(new int[]{-10});
triangle.add(l);*/
System.out.println(minimumTotal.minimumTotal2(triangle));
}
int min = Integer.MAX_VALUE;
//此方法最优
public int minimumTotal2(List<List<Integer>> triangle) {
//排除特殊情况
if (triangle.size() == 1) {
return triangle.get(0).get(0);
}
//要处理的第几行,上一次的结果,全部数据
//相较于上一种减少了空间复杂度
deal(1, new int[]{triangle.get(0).get(0)}, triangle);
return min;
}
public void deal(int i, int[] pre, List<List<Integer>> triangle) {
//全部处理完之后找出最小值
if (i==triangle.size()) {
for (int p : pre) {
min = Math.min(min, p);
}
return;
}
//定义本次执行的结果数组
int[] dp = new int[triangle.get(i).size()];
List<Integer> l = triangle.get(i);
for (int j = 0; j < l.size(); j++) {
if (j == 0) {//最左边
dp[j] = pre[j] + l.get(j);
} else if (j == (l.size()-1)){//最右边
dp[j] = pre[j-1] + l.get(j);
} else {//中间
dp[j] = Math.min(pre[j], pre[j-1]) + l.get(j);
}
}
//继续递归
deal(i+1, dp, triangle);
}
}
LeetCode测试结果