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 public class Solution { 2 public int minimumTotal(List<List<Integer>> triangle) { 3 if (triangle==null || triangle.size()==0) return -1; 4 int n = triangle.size(); 5 int minimum = Integer.MAX_VALUE; 6 int[] res = new int[n]; 7 res[0] = triangle.get(0).get(0); 8 for (int i=1; i<n; i++) { 9 for (int j=i; j>=0; j--) { 10 if (j == i) res[j] = triangle.get(i).get(j) + res[j-1]; 11 else if (j == 0) res[j] = triangle.get(i).get(j) + res[j]; 12 else { 13 res[j] = triangle.get(i).get(j) + Math.min(res[j-1], res[j]); 14 } 15 } 16 } 17 for (int elem : res) { 18 if (elem < minimum) { 19 minimum = elem; 20 } 21 } 22 return minimum; 23 } 24 }
网上看了一些其他人的做法,发现了差不多的code:
这是一道动态规划的题目,求一个三角形二维数组从顶到低端的最小路径和。思路是维护到某一个元素的最小路径和,那么在某一个元素i,j的最小路径和就是它上层对应的相邻两个元素的最小路径和加上自己的值,递推式是sum[i][j]=min(sum[i-1][j-1],sum[i-1][j])+triangle[i][j]。最后扫描一遍最后一层的路径和,取出最小的即可。每个元素需要维护一次,总共有1+2+...+n=n*(n+1)/2个元素,所以时间复杂度是O(n^2)。而空间上每次只需维护一层即可(因为当前层只用到上一层的元素),所以空间复杂度是O(n)。
1 public int minimumTotal(ArrayList<ArrayList<Integer>> triangle) { 2 if(triangle == null || triangle.size() == 0) 3 return 0; 4 if(triangle.size()==1) 5 return triangle.get(0).get(0); 6 int[] sums = new int[triangle.size()]; 7 sums[0] = triangle.get(0).get(0); 8 for(int i=1;i<triangle.size();i++) 9 { 10 sums[i] = sums[i-1]+triangle.get(i).get(i); 11 for(int j=i-1;j>=1;j--) 12 { 13 sums[j] = (sums[j]<sums[j-1]?sums[j]:sums[j-1]) + triangle.get(i).get(j); 14 } 15 sums[0] = sums[0]+triangle.get(i).get(0); 16 17 } 18 int minimum = sums[0]; 19 for(int i=1;i<sums.length;i++) 20 { 21 if(sums[i]<minimum) 22 { 23 minimum = sums[i]; 24 } 25 } 26 return minimum; 27 }