问题描述
思路
思路就是动态规划,如果采用递归会超时,其最主要的是写出状态转移方程。主要就是dp求解的过程中的边界值的细节要做好。
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
我是从递归改到dp的。
Code
超时的递归
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);
}
}
改良的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;
}
}