问题:
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.
解决:
① 动态规划。用一个二维数组存储从第一行到某行某个数的经过数的最小值,这是空间为o(n*n)。
递推的过程为:
递推公式为:
dp[0][0] = triangle[0][0]
dp[i][0] = triangle[i][0] + dp[i - 1][0]
dp[i][i] = tirangle[i][i] + dp[i - 1][i - 1]
dp[i][j] = Math.min(dp[i - 1][j - 1],dp[i - 1][j]) +triangle[i][j]。
空间复杂度为O(n^2),时间复杂度为O(n^2)。
class Solution { // 8ms
public int minimumTotal(List<List<Integer>> triangle) {
int row = triangle.size();
if(row == 0) return 0;
int[][] dp = new int[row][row];
int minSum = Integer.MAX_VALUE;
List<Integer> list0 = triangle.get(0);
if(list0.size() == 0) return 0;
if(row == 1) return list0.get(0);
dp[0][0] = list0.get(0);
for (int i = 1;i < row ;i ++ ) {
List<Integer> list = triangle.get(i);
for (int j = 0;j < list.size() ;j ++ ) {
if(j == 0){
dp[i][j] = dp[i - 1][j] + list.get(j);
}else if(j == list.size() - 1){
dp[i][j] = dp[i - 1][j - 1] + list.get(j);
}else{
dp[i][j] = Math.min(dp[i - 1][j - 1],dp[i - 1][j]) + list.get(j);
}
if(i == row - 1){
if(minSum > dp[i][j]){
minSum = dp[i][j];
}
}
}
}
return minSum;
}
}
② 将三角形看成倒三角形即可,从后面的行求到前面的行,这样就可以用一个一维数组保存到当前行的某个数的最小和。空间复杂度为O(n)。
class Solution { //8ms
public int minimumTotal(List<List<Integer>> triangle) {
int row = triangle.size();
if(row == 0) return 0;
int[] dp = new int[row + 1];
for (int i = row - 1;i >= 0 ;i -- ) {
List<Integer> list = triangle.get(i);
for (int j = 0;j < list.size();j ++ ) {
dp[j] = Math.min(dp[j + 1],dp[j]) + list.get(j);
}
}
return dp[0];
}
}
③ 将处理方法单独提取出来。
class Solution { //7ms
public int minimumTotal(List<List<Integer>> triangle) {
int n = triangle.size();
return getMin(triangle,new int[triangle.size() + 1][triangle.size() + 1],0,0);
}
public int getMin(List<List<Integer>> triangle,int dp[][],int i,int j){
if(dp[i][j] != 0)
return dp[i][j];
int res = triangle.get(i).get(j);
if(i < triangle.size() - 1){
res += Math.min(getMin(triangle,dp,i + 1,j),getMin(triangle,dp,i + 1,j + 1));
}
dp[i][j] = res;
return res;
}
}