LeetCode-931 minimum falling path sum 下降路径最小和

题目链接

LeetCode 周赛 108场 C题

https://leetcode-cn.com/contest/weekly-contest-108/problems/minimum-falling-path-sum/

题意

        比较简单的,也就是说上一层下降的话只能间隔1位下降,例如下图:

看懂给的例子就理解题意了。

题解

        C题着实感觉自己脑子不太灵光了QAQ,总是在不坑的题上坑。刚开始就想着用DFS爽的一匹,果断超时。剪枝以后还是超时。直接忘记了因为递归比较费时间,既然能DFS了,那反向操作用数组存最小值直接改成DP岂不稳得一匹?然后就跑去写D题了,当时根本没想到DP还以为有什么剪枝没想到。。。

        如果是DP的话其实就是比较简单的求和DP反向写。开二维数组,存第一行的所有数,从第二行开始,找每个位置能从上一行哪些位置下降过来,将其中的最小值赋值就可以了。其实就是上面的图,将指向反过来看就可以了:

那么除了两端的特殊情况,其他都是能从3个位置下降过来,有状态转移方程:

dp[i][j] = A[i][j] + Min(dp[i-1][j-1],dp[i-1][j],dp[i-1][j+1])

注意判定最左边和最右边两种情况就行了。

        另外,竟然破天荒给了数据范围,当n = 1的时候只有一个下降数组就是本身,这个判定一下就行。最终答案要for循环遍历一下最下面一层,看最小值是多少。最小值就是答案。

Java 代码

class Solution {
    public static int[][] dp;
    
    public static int Min(int a,int b){
        return a < b ? a : b;
    }
    
    public int minFallingPathSum(int[][] A) {
        int len = A[0].length;
        if(len == 1) return A[0][0];
        dp = new int[len][len];
        for(int i = 0;i < len;i++){
            dp[0][i] = A[0][i];
        }
        for(int i = 1;i < len;i++){
            for(int j = 0;j < len;j++){
                if(j == 0){
                    dp[i][j] = A[i][j] + Min(dp[i-1][j],dp[i-1][j+1]);
                }else{
                    if(j == len-1){
                        dp[i][j] = A[i][j] + Min(dp[i-1][j],dp[i-1][j-1]);
                    }else{
                        dp[i][j] = A[i][j] + Min(Min(dp[i-1][j],dp[i-1][j+1]),dp[i-1][j-1]);
                    }
                }
            }
        }
        int ans = 20000;
        for(int i = 0;i < len;i++){
            ans = Min(ans,dp[len-1][i]);
        }
        return ans;
    }
}

DFS

        纪念一下日常智障操作,TLE代码:

class Solution {
    public static int ans;
    public static int limit;
    
    public static void solve(int line,int index,int val,int[][] temp){
        if(line == limit-1){
            ans = ans > val ? val : ans;
            return;
        }
        if(val - 100*(limit-1-line) >= ans) return;
        solve(line+1,index,val+temp[line+1][index],temp);
        if(index == 0){
            solve(line+1,index+1,val+temp[line+1][index+1],temp);
        }else{
            if(index == limit-1){
                solve(line+1,index-1,val+temp[line+1][index-1],temp);
            }else{
                solve(line+1,index+1,val+temp[line+1][index+1],temp);
                solve(line+1,index-1,val+temp[line+1][index-1],temp);
            }
        }
    }
    
    public int minFallingPathSum(int[][] A) {
        ans = 20000;
        limit = A[0].length;
        if(limit == 1) return A[0][0];
        for(int i = 0;i < limit;i++){
            solve(0,i,A[0][i],A);
        }
        return ans;
    }
}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值