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

版权声明:转载请注明原址,有错误欢迎指出 https://blog.csdn.net/iwts_24/article/details/83502104

题目链接

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;
    }
}

猜你喜欢

转载自blog.csdn.net/iwts_24/article/details/83502104