给定一个三角形,找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的结点上。
例如,给定三角形:
[
[2],
[3,4],
[6,5,7],
[4,1,8,3]
]
自顶向下的最小路径和为 11(即,2 + 3 + 5 + 1 = 11)。
说明:
如果你可以只使用 O(n) 的额外空间(n 为三角形的总行数)来解决这个问题,那么你的算法会很加分。
空间复杂度O(n^2)
自底向上遍历,每个dp存的是当前位置的最小值
例如:dp[2][1]处就是他自己的值加上下一行中与他相邻的两个值中的最小值
动态方程:dp[i][j] = triangle.get(i).get(j)+java.lang.Math.min(dp[i+1][j], dp[i+1][j+1]);
提交的代码:
class Solution {
public int minimumTotal(List<List<Integer>> triangle) {
int n = triangle.size();
int[][] dp = new int[n][triangle.get(n-1).size()];
int i,j;
for(i=0;i<triangle.get(n-1).size();i++)
{
dp[n-1][i] = triangle.get(n-1).get(i);
}
for(i=n-2;i>=0;i--)
{
for(j=0;j<triangle.get(i).size();j++)
{
dp[i][j] = triangle.get(i).get(j)+java.lang.Math.min(dp[i+1][j], dp[i+1][j+1]);
}
}
return dp[0][0];
}
}
完整的代码:
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main
{
public static int minimumTotal(List<List<Integer>> triangle) {
int n = triangle.size();
int[][] dp = new int[n][triangle.get(n-1).size()];
int i,j;
for(i=0;i<triangle.get(n-1).size();i++)
{
dp[n-1][i] = triangle.get(n-1).get(i);
}
for(i=n-2;i>=0;i--)
{
for(j=0;j<triangle.get(i).size();j++)
{
dp[i][j] = triangle.get(i).get(j)+java.lang.Math.min(dp[i+1][j], dp[i+1][j+1]);
}
}
return dp[0][0];
}
public static void main(String[] args)
{
//[
//[2],
//[3, 4],
//[6, 5, 7],
//[4, 1, 8, 3]
//]
List<List<Integer>> list = new ArrayList<>();
List<Integer> subList0 = new ArrayList<>();
subList0.add(2);
List<Integer> subList1 = new ArrayList<>();
subList1.add(3);
subList1.add(4);
List<Integer> subList2 = new ArrayList<>();
subList2.add(6);
subList2.add(5);
subList2.add(7);
List<Integer> subList3 = new ArrayList<>();
subList3.add(4);
subList3.add(1);
subList3.add(8);
subList3.add(3);
list.add(subList0);
list.add(subList1);
list.add(subList2);
list.add(subList3);
System.out.println(minimumTotal(list));
}
}