120.三角形最小路径和 (从dfs+记忆化到动态规划dp)


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);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值