LeetCode刷题--- 下降路径最小和

个人主页:元清加油_【C++】,【C语言】,【数据结构与算法】-CSDN博客

个人专栏

力扣递归算法题

 http://t.csdnimg.cn/yUl2I

【C++】    

​​​​​​http://t.csdnimg.cn/6AbpV

数据结构与算法

 ​​​http://t.csdnimg.cn/hKh2l


前言:这个专栏主要讲述动态规划算法,所以下面题目主要也是这些算法做的  

我讲述题目会把讲解部分分为3个部分:
1、题目解析

2、算法原理思路讲解

3、代码实现


下降路径最小和

题目链接:下降路径最小和

题目

给你一个 n x n 的 方形 整数数组 matrix ,请你找出并返回通过 matrix 的下降路径  最小和 。

下降路径 可以从第一行中的任何元素开始,并从每一行中选择一个元素。在下一行选择的元素和当前行所选元素最多相隔一列(即位于正下方或者沿对角线向左或者向右的第一个元素)。具体来说,位置 (row, col) 的下一个元素应当是 (row + 1, col - 1)(row + 1, col) 或者 (row + 1, col + 1) 。

示例 1:

输入:matrix = [[2,1,3],[6,5,4],[7,8,9]]
输出:13
解释:如图所示,为和最小的两条下降路径

示例 2:

输入:matrix = [[-19,57],[-40,-5]]
输出:-59
解释:如图所示,为和最小的下降路径

提示:

  • n == matrix.length == matrix[i].length
  • 1 <= n <= 100
  • -100 <= matrix[i][j] <= 100

解法

题目解析

  1. 给你一个mxn方形整数数组 matrix ,请你找出并返回通过 matrix 的下降路径最小和 。
  2. 下降路径 可以从第一行中的任何元素开始,并从每一行中选择一个元素。
  3. 在下一行选择的元素和当前行所选元素最多相隔一列(即位于正下方或者沿对角线向左或者向右的第一个元素)。

算法原理讲解

我们这题使用动态规划,我们做这类题目可以分为以下五个步骤

  1. 状态显示
  2. 状态转移方程
  3. 初始化(防止填表时不越界)
  4. 填表顺序
  5. 返回值

  • 状态显示
dp[i][j] 表⽰:到达 [i, j] 位置时,所有下降路径中的最⼩和。
  • 状态转移方程
对于普遍位置 [i, j] ,根据题意得,到达 [i, j] 位置可能有三种情况:
  • 从正上⽅ [i - 1, j] 位置转移到 [i, j] 位置;
  • 从左上⽅ [i - 1, j - 1] 位置转移到 [i, j] 位置;
  • 从右上⽅ [i - 1, j + 1] 位置转移到 [i, j] 位置;
我们要的是三种情况下的「最⼩值」,然后再加上矩阵在 [i, j] 位置的值。 于是 dp[i][j] = min(dp[i - 1][j], min(dp[i - 1][j - 1], dp[i - 1][j + 1])) + matrix[i][j]。
  • 初始化(防止填表时不越界)
在本题中,需要「加上⼀⾏」,并且「加上两列」。所有的位置都初始化为⽆穷⼤,然后将第⼀⾏
初始化为 0 即可。
  • 填表顺序

根据「状态表⽰」,填表的顺序是「从上往下」。

  • 返回值

注意这⾥不是返回 dp[m][n] 的值!
题⽬要求「只要到达最后⼀⾏」就⾏了,因此这⾥应该返回「 dp 表中最后⼀⾏的最⼩值」。

代码实现

  • 时间复杂度:O(2^{n}),需要计算每个坐标的和最小下降路径。
  • 空间复杂度:O(2^{n}),需要记录每个坐标的和最小下降路径。因为每个坐标的和最小下降路径仅与上一行有关,因此可以使用滚动数组,使得空间复杂度降低为 O(n)。
class Solution {
public:
    int minFallingPathSum(vector<vector<int>>& matrix) 
    {
        // 1.状态显示---------------》dp[i][j]表示最小路径
        // 2.状态转移方程
        // 3.初始化
        // 4.填表方向
        // 5.返回值


        int n = matrix.size();
        vector<vector<int>> dp(n + 1, vector<int>(n + 2, INT_MAX));

        // 初始化第一行
        for (int j = 0; j < n + 2; j++)
        {
            dp[0][j] = 0;
        }

        // 填表
        for (int i = 1; i <= n; i++)
        {
            for (int j = 1; j <= n; j++)
            {
                dp[i][j] = min(dp[i - 1][j - 1], min(dp[i - 1][j], dp[i - 1][j + 1])) + matrix[i - 1][j - 1];
            }
        }

        int ret = INT_MAX;

        for (int i = 1; i <= n; i++)
        {
            ret = min(ret, dp[n][i]);
        }

        return ret;
    }
};

相关推荐

最近更新

  1. TCP协议是安全的吗?

    2024-01-09 22:32:01       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-09 22:32:01       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-09 22:32:01       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-09 22:32:01       18 阅读

热门阅读

  1. 发音纠正(每日职场英语)

    2024-01-09 22:32:01       38 阅读
  2. AI智能电销器人需要注意哪些问题呢

    2024-01-09 22:32:01       38 阅读
  3. 使用 LLVM clang C/C++ 编译器编译 OpenSSL 3.X库

    2024-01-09 22:32:01       33 阅读
  4. 变量和函数提升(js的问题)

    2024-01-09 22:32:01       40 阅读
  5. 运行时类型信息 typeid、type_info...(C++)

    2024-01-09 22:32:01       32 阅读
  6. Go语言实现数据结构栈和队列

    2024-01-09 22:32:01       26 阅读
  7. linux 网络驱动之net_device 结构介绍

    2024-01-09 22:32:01       29 阅读
  8. Python基础(二):数值类型及其运算

    2024-01-09 22:32:01       38 阅读
  9. 关于Tomcat源码学习 这里是一些建议

    2024-01-09 22:32:01       32 阅读