题目描述
给定一个三角形,找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的结点上。
例如,给定三角形:
[
[2],
[3,4],
[6,5,7],
[4,1,8,3]
]
递归思路
1.既然每次下移都只有两个位置选择,我们完全可以暴力递归所有路径的答案,然后选择最小的即可。
2.每次递归时都需要传入当前行(curRow)、当前行所在索引(rowIndex)以及当前的和(curSum),递归出口设置为最后一层。
Java代码实现(暴力递归)
public int minimumTotal(List<List<Integer>> triangle) {
if(triangle.size() == 0)
return 0;
int res = minimumTotal(triangle,0,0,0);
return res;
}
private int minimumTotal(List<List<Integer>> triangle,int curRow,int rowIndex,int curSum) {
if(curRow == triangle.size()-1)
return curSum+triangle.get(curRow).get(rowIndex);
else{
int c1 = minimumTotal(triangle,curRow+1,rowIndex,curSum+triangle.get(curRow).get(rowIndex));
int c2 = minimumTotal(triangle,curRow+1,rowIndex+1,curSum+triangle.get(curRow).get(rowIndex));
return Math.min(c1,c2);
}
}
动态规划思路
1.通过上面的递归,我们可以找到状态转移方程,即dp[i][j] = min(dp[i+1][j],dp[i+1][j+1])+dp[i][j];
2.可以声明一个dp数组用于存放结果集,将n-1行,也就是底部赋值后,从n-2行按照状态转移方程迭代求解。
3.最后返回dp[0][0]作为结果即可。
Java代码实现(动态规划)
public int minimumTotal(List<List<Integer>> triangle) {
if(triangle.size() == 0)
return 0;
int[][] dp = new int[triangle.size()][triangle.size()];
for (int i = triangle.size()-1; i >= 0 ; i--) {
dp[triangle.size()-1][i] = triangle.get(triangle.size()-1).get(i);
}
for (int i = triangle.size()-2; i >=0 ; i--) {
for (int j = 0; j < triangle.get(i).size(); j++) {
dp[i][j] = Math.min(dp[i+1][j],dp[i+1][j+1])+triangle.get(i).get(j);
}
}
return dp[0][0];
}
网友评论