leetcode 120:三角形的最小路径和
给定一个金字塔三角形,找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的结点上。
相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 + 1 的两个结点。
例如,给定三角形:
[
[2],
[3,4],
[6,5,7],
[4,1,8,3]
]
自顶向下的最小路径和为 11(即,2 + 3 + 5 + 1 = 11)。
1.首先,将金字塔三角形看成一个直角三角形
[2],
[3,4],
[6,5,7],
[4,1,8,3]
2.自顶向下的最小路径和,也就是从最上面节点到下面各个节点的不同路径和比较,取最小值

3.最下面节点4,只能从上面节点6走下来;最下面节点1,可能从上面节点6和5走下来的;最下面节点8,可能从上面节点5和7走下来的;最下面节点3,只能从上面节点7走下来的;
4.用triangle[m][n]表示三角形m行n列的节点数组,用dp[i][j]表示从(0行,0列)到(i行,j列)的最小路径和;
则针对最左端:dp[i][j] = dp[i-1][j] + triangle[i][j];只能从上面一行同一列的节点走下来,路径和要加上本节点的值
针对最右端:dp[i][j] = dp[i-1][j-1] + triangle[i][j];只能从上面一行同一列的前一列节点走下来,路径和要加上本节点的值
中间部分:dp[i][j] = min(dp[i-1][j], dp[i-1][j-1]) + triangle[i][j];可能从上面一行同一列的节点走下来,也可能从上面一行同一列的前一列节点走下来,路径和要加上本节点的值
......
层层递推,最终递推到dp[1][1]和dp[0][0],而这些初始状态是已知的。dp[0][0]=2
代码部分
1 public int minimumTotal(List<List<Integer>> triangle) { 2 if (triangle == null || triangle.size() == 0) { 3 return 0; 4 } 5 int row = triangle.size(); 6 int column = triangle.get(row - 1).size(); 7 8 int[][] dp = new int[row][column]; 9 dp[0][0] = triangle.get(0).get(0); 10 int res = Integer.MAX_VALUE; 11 12 for (int i = 1; i < row; i++) { 13 for (int j = 0; j <= i; j++) { 14 if (j == 0) { 15 // 最左端特殊处理 16 dp[i][j] = dp[i - 1][j] + triangle.get(i).get(j); 17 } else if (j == i) { 18 // 最右端特殊处理 19 dp[i][j] = dp[i - 1][j - 1] + triangle.get(i).get(j); 20 } else { 21 dp[i][j] = Math.min(dp[i - 1][j], dp[i - 1][j - 1]) + triangle.get(i).get(j); 22 } 23 } 24 } 25 26 // dp最后一行记录了最小路径和 27 for (int i = 0; i < column; i++) { 28 res = Math.min(res, dp[row - 1][i]); 29 } 30 System.out.println("最小路径和:"+res); 31 return res; 32 }