120. Triangle
题目:
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.
链接: http://leetcode.com/problems/triangle/
题解:
自底向上dp。虽然是个简单题, 但自己现在也能写出一些比较简练的代码了,是进步,要肯定。晚上东方串店撸串去!
Time Complexity - O(n),Space Complexity - O(1)。
public class Solution { public int minimumTotal(List<List<Integer>> triangle) { if(triangle == null || triangle.size() == 0) return 0; for(int i = triangle.size() - 2; i >= 0; i--) { for(int j = 0; j < triangle.get(i).size(); j++) { triangle.get(i).set(j, triangle.get(i).get(j) + Math.min(triangle.get(i + 1).get(j), triangle.get(i + 1).get(j + 1))); } } return triangle.get(0).get(0); } }
二刷:
一般来说对于题目给出的数据结构比如Tree或者List<>不要轻易修改。我们另外建立一个数组来dp就好了。这里主要使用了自底向上的思路,先初始化dp数组为triangle的最后一行,再用转移方程dp[i] = triangle.get(i).get(j) + Math.min(dp[i], dp[i + 1])就好了。要注意边界条件。
Java:
Time Complexity - O(n),Space Complexity - O(n)。
public class Solution { public int minimumTotal(List<List<Integer>> triangle) { if (triangle == null || triangle.size() == 0) { return Integer.MIN_VALUE; } int rowNum = triangle.size(); List<Integer> lastRow = triangle.get(rowNum - 1); int[] paths = new int[rowNum]; for (int i = 0; i < lastRow.size(); i++) { paths[i] = lastRow.get(i); } for (int i = rowNum - 2; i >= 0; i--) { for (int j = 0; j < triangle.get(i).size(); j++) { paths[j] = triangle.get(i).get(j) + Math.min(paths[j], paths[j + 1]); } } return paths[0]; } }
三刷:
Java:
in-place:
public class Solution { public int minimumTotal(List<List<Integer>> triangle) { int min = Integer.MAX_VALUE; if (triangle == null || triangle.size() == 0) return Integer.MAX_VALUE; for (int i = triangle.size() - 2; i >= 0; i--) { for (int j = 0; j < triangle.get(i).size(); j++) { triangle.get(i).set(j, triangle.get(i).get(j) + Math.min(triangle.get(i + 1).get(j), triangle.get(i + 1).get(j + 1))); } } return triangle.get(0).get(0); } }
Use auxiliary list
public class Solution { public int minimumTotal(List<List<Integer>> triangle) { int min = Integer.MAX_VALUE; if (triangle == null || triangle.size() == 0) return Integer.MAX_VALUE; List<Integer> res = new ArrayList<>(triangle.get(triangle.size() - 1)); for (int i = triangle.size() - 2; i >= 0; i--) { for (int j = 0; j < triangle.get(i).size(); j++) { res.set(j, triangle.get(i).get(j) + Math.min(res.get(j), res.get(j + 1))); } } return res.get(0); } }
Reference:
https://leetcode.com/discuss/5337/dp-solution-for-triangle
https://leetcode.com/discuss/10131/my-java-version-solution-with-o-n-space-accepted
https://leetcode.com/discuss/23544/my-8-line-dp-java-code-4-meaningful-lines-with-o-1-space
https://leetcode.com/discuss/20296/bottom-up-5-line-c-solution