Problem Description
train of thought
The idea is dynamic programming. If recursion is used, it will time out. The most important thing is to write the state transition equation. The main thing is to do a good job in the details of the boundary value in the process of dp solution.
f u n ( d e p t h , i ) = { m i n ( f u n ( d e p t h − 1 , i ) , f u n ( d e p t h , i − 1 ) ) + t r i a n g l e [ d e p t h ] [ i ] d e p t h > 1 , 0 < = i < t r i a n g l e [ d e p t h − 1 ] . l e n g t h f u n ( d e p t h − 1 , i ) + t r i a n g l e [ d e p t h ] [ i ] d e p t h > 1 , i − 1 < 0 f u n ( d e p t h − 1 , i − 1 ) + t r i a n g l e [ d e p t h ] [ i ] d e p t h > 1 , i > = t r i a n g l e [ d e p t h − 1 ] . l e n g t h t r i a n g l e [ 0 ] [ 0 ] d e p t h = 1 fun(depth, i)=\begin{cases} min(fun(depth-1, i), fun(depth, i-1)) + triangle[depth][i] & depth > 1, 0 <= i < triangle[depth-1].length \\ fun(depth-1, i) + triangle[depth][i] & depth > 1, i-1 < 0 \\ fun(depth-1, i-1) + triangle[depth][i] & depth > 1, i >= triangle[depth-1].length \\ triangle[0][0] & depth = 1 \end{cases} fun(depth,i)=⎩⎪⎪⎪⎨⎪⎪⎪⎧min(fun(depth−1,i),fun(depth,i−1))+triangle[depth][i]fun(depth−1,i)+triangle[depth][i]fun(depth−1,i−1)+triangle[depth][i]triangle[0][0]depth>1,0<=i<triangle[depth−1].lengthdepth>1,i−1<0depth>1,i>=triangle[depth−1].lengthdepth=1
I changed from recursive to dp.
Code
recursion with timeout
class Solution {
public int minimumTotal(List<List<Integer>> triangle) {
if (triangle.size() == 0) return 0;
return dp(triangle, 0, 0);
}
public int dp(List<List<Integer>> triangle, int x, int depth) {
if (depth >= triangle.size()) return 0;
if (x >= triangle.get(depth).size()) return 0;
return Math.min(dp(triangle, x, depth+1), dp(triangle, x+1, depth+1)) + triangle.get(depth).get(x);
}
}
Improved DP
class Solution {
public int minimumTotal(List<List<Integer>> triangle) {
if (triangle.size() == 0) return 0;
int[][] dp = new int[triangle.size()][triangle.get(triangle.size()-1).size()];
dp[0][0] =triangle.get(0).get(0);
for (int i = 1; i < triangle.size(); i++) {
int len = triangle.get(i).size();
for (int j = 0; j < len; j++) {
int a = Integer.MAX_VALUE;
int b = Integer.MAX_VALUE;
if (j - 1 >= 0) a = dp[i-1][j-1];
if (j < len -1) b = dp[i-1][j];
dp[i][j] = Math.min(a, b) + triangle.get(i).get(j);
}
}
int[] ints = dp[dp.length - 1];
int n = ints[0];
for (int i = 1; i < ints.length; i++) if (n > ints[i]) n = ints[i];
return n;
}
}