题目描述
给定一个三角形,找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的结点上。
例如,给定三角形:
[ [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]; }