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 is 11
(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.
【题目分析】
给定一个三角,三角的结构和题目中给出的例子相同,找出从三角的顶部到底部的一条路径,使得这条路径经过的元素之和最小。每一步只能移动到下一行中和当前元素相邻的位置。
【思路】
1. triangle元素改变的方法
既然是从上往下移动,我们可以把上一层的元素的值加到下一层的相邻元素上,如果下一层某个元素在上一层中有两个相邻的元素,那个就把这两个元素中较小的那个加到下一层元素上。过程如下:
--->或者
从最后一行的值中我们可以选出最小的那个值,当然这个过程也可以反着进行,从最后一行向上加,上一层元素从它相邻的两个下层元素中选择较小的那个加到它本身。
2. triangle元素不改变的方法
这个方法的思路与上个方法是相同的,只不过这个方法不会改变三角中的元素,而是维持一个数组来存储这个改变的过程。例如从下往上的遍历过程,先把最后一行赋值给数组,从数组相邻元素中选取较小的那个加上这两个元素在上一层的共同相邻元素,这个新值依旧存储在数组中。这时空间复杂度为O(n)。
【java代码1】从上往下遍历,triangle元素改变
1 public class Solution { 2 public int minimumTotal(List<List<Integer>> triangle) { 3 if(triangle == null || triangle.size() == 0) return 0; 4 int triszie = triangle.size(); 5 6 List<Integer> clist = triangle.get(0); 7 for(int i = 0; i < triszie - 1; i++){ 8 List<Integer> nlist = triangle.get(i+1); 9 nlist.set(0, clist.get(0) + nlist.get(0)); 10 for(int j = 1; j <= i; j++){ 11 int value = Math.min(clist.get(j), clist.get(j-1)) + nlist.get(j); 12 nlist.set(j, value); 13 } 14 nlist.set(i+1, clist.get(i) + nlist.get(i+1)); 15 clist = nlist; 16 } 17 18 int min = clist.get(0); 19 for(int i = 1; i < clist.size(); i++){ 20 min = Math.min(min, clist.get(i)); 21 } 22 return min; 23 } 24 }
【java代码2】从下往上,triangle元素不改变
1 public class Solution { 2 public int minimumTotal(List<List<Integer>> triangle) { 3 if(triangle == null || triangle.size() == 0) return 0; 4 int triszie = triangle.size(); 5 int[] dp = new int[triszie]; 6 7 for(int i = triszie - 1; i >= 0; i--){ 8 for(int j = 0; j <= i; j++){ 9 if(i == triszie - 1) dp[j] = triangle.get(i).get(j); 10 else dp[j] = Math.min(dp[j],dp[j+1]) + triangle.get(i).get(j); 11 } 12 } 13 return dp[0]; 14 } 15 }