120.三角形最小路径和
dfs+记忆化
/**(超时)
* 算法一:dfs+备忘录 (自顶向下)
*/
public int minimumTotal(List<List<Integer>> triangle) {
if (triangle == null || triangle.size() == 0) return 0;
return BT(triangle,1,triangle.get(0).get(0),0,new HashMap<int[],Integer>());
}
private int BT(List<List<Integer>> triangle,int floor,int sum,int index,HashMap<int[],Integer> buff){
if (floor >= triangle.size())
return sum;
if (buff.containsKey(new int[]{floor,index}))
return buff.get(new int[]{floor,index});
int ans1 = BT(triangle,floor+1,sum+triangle.get(floor).get(index),index,buff);
int ans2 = BT(triangle,floor+1,sum+triangle.get(floor).get(index+1),index+1,buff);
int min = Math.min(ans1,ans2);
buff.put(new int[]{floor,index},min);
return min;
}
动态规划
/**(6ms)
* 算法二:dp,套模板
*/
public int minimumTotal3(List<List<Integer>> triangle){
if (triangle == null || triangle.size() == 0) return 0;
//1.状态:层数,位置;选择:最小路径是否通过该元素(即是否选择)
//2.dp[i][j]=x,第i层第i个位置的元素为起点往下的最短路径和为x
int n = triangle.size();
int maxM = triangle.get(n-1).size();
int[][] dp = new int[n][maxM];
//3.base case
for (int i = 0; i < maxM; i++) {//最底下一层
dp[n-1][i] = triangle.get(n-1).get(i);
}
//4.状态转移
for (int i = n-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];
}
压缩后
public int minimumTotal2(List<List<Integer>> triangle) {
if (triangle == null || triangle.size() == 0) return 0;
for (int i = triangle.size()-2; i >=0 ; i--) {
for (int j = 0; j < triangle.get(i).size(); j++) {
triangle.get(i).set(j,Math.min(triangle.get(i+1).get(j),triangle.get(i+1).get(j+1))+triangle.get(i).get(j));
}
}
return triangle.get(0).get(0);
}