当前位置: 首页 > news >正文

2.4路径问题专题:LeeCode 931.下降路径最小和

动态规划解决最小下降路径和问题

1. 题目链接

LeetCode 931. 最小下降路径和

2. 题目描述

给定一个 n x n 的整数矩阵 matrix,找到一条从第一行到最后一行的下降路径,使得路径上的数字和最小。下降路径可以从第一行的任意元素出发,每一步可以选择位于下一行正下方、左下方或右下方的元素。例如,位于 (i, j) 的元素可以下降到 (i+1, j-1)(i+1, j)(i+1, j+1)

3. 示例分析

示例输入

matrix = [[2,1,3],
          [6,5,4],
          [7,8,9]]

输出13
解释:最小下降路径为 1 → 5 → 7,路径和为 1 + 5 + 7 = 13

4. 算法思路

动态规划(Dynamic Programming)

使用动态规划解决该问题的核心思想是:定义 dp[i][j] 表示从第一行到达第 i 行第 j 列的最小路径和。为了处理边界条件(如矩阵边缘的列),我们扩展 dp 数组的边界,使其维度为 (n+1) x (n+2)

状态转移方程

对于每个位置 (i, j),其路径和的最小值由上一行的三个可能的位置决定:

dp[i][j] = matrix[i-1][j-1] + min(dp[i-1][j-1], dp[i-1][j], dp[i-1][j+1])

其中,matrix[i-1][j-1] 是当前位置的值,dp[i-1][...] 是上一行左、中、右三个位置的路径和的最小值。

初始化
  • dp[0][...] = 0:第一行的所有位置初始化为0,表示从虚拟的第0行出发的路径和为0。
  • 其余位置初始化为 INT_MAX,表示尚未计算。

5. 边界条件与注意事项

  1. 矩阵大小为1的情况:当 n=1 时,直接返回矩阵中唯一的元素。
  2. 索引转换:由于 dp 数组比原矩阵多一圈,访问 matrix 时需要将索引调整为 i-1j-1
  3. 处理边缘列:在矩阵的最左列(j=1)和最右列(j=n),需要确保不会访问到无效的列(如 j=0j=n+1),此时这些位置的 dp 值为 INT_MAX,不影响取最小值。

6. 代码实现

class Solution {
public:
    int minFallingPathSum(vector<vector<int>>& matrix) {
        int n = matrix.size();
        vector<vector<int>> dp(n + 1, vector<int>(n + 2, INT_MAX));
        // 初始化:从虚拟的第0行出发,路径和为0
        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] = matrix[i - 1][j - 1] + 
                           min(min(dp[i - 1][j - 1], dp[i - 1][j]), dp[i - 1][j + 1]);
            }
        }

        // 遍历最后一行,寻找最小值
        int ret = INT_MAX;
        for (int j = 0; j < n + 2; j++) {
            ret = min(ret, dp[n][j]);
        }
        return ret;
    }
};

代码解释

  1. 初始化 dp 数组:第0行初始化为0,其他位置为 INT_MAX
  2. 填充 dp 数组:遍历每一行,根据上一行的三个相邻位置的最小值更新当前值。
  3. 获取结果:遍历最后一行的所有列,找到最小值作为最终结果。

通过这种动态规划的方式,时间复杂度为 O(n²),空间复杂度为 O(n²),能够高效解决该问题。

http://www.dtcms.com/a/109250.html

相关文章:

  • Shiro学习(四):Shiro对Session的处理和缓存
  • MyBatis 动态SQL 详解!
  • C# 从代码创建选型卡+表格
  • 用nodejs连接mongodb数据库对标题和内容的全文本搜索,mogogdb对文档的全文本索引的设置以及用node-rs/jieba对标题和内容的分词
  • Git Restore 命令详解与实用示例
  • leecode第18天
  • 代码拟有感
  • 跟我学C++中级篇——In-Place Construction 和placement new
  • React-router v7 第二章(路由模式)
  • Vant 上传图片闪动问题的原因与解决方案
  • Shell脚本编程之大括号扩展
  • Spring 核心技术解析【纯干货版】- XX:Spring 测试模块 Spring-Test 模块精讲
  • 【文献研究】铝对热冲压加热过程中锌氧化的影响
  • 【C++ SIMD】第3篇:数据对齐与跨步访问(Windows/VS2022版)——以AVX为例
  • Hadoop集群---运维管理和技巧
  • 【Kafka基础】单机安装与配置指南,从零搭建环境
  • NodeJS--NPM介绍使用
  • 训练或微调以生成新组合结构
  • Leetcode 927 -- 思维
  • Win10定时任务计划无法显示要执行的EXE任务程序界面,问题解决办法
  • 什么是检索增强生成(RAG)
  • 7-3 逆序的三位数
  • PyTorch 深度学习实战(33):联邦学习与隐私保护
  • CROSS JOIN第一个表中的每一行与第二个表中的每一行组合
  • 商城系统:电商时代的核心驱动力
  • Cribl 修改字段rename
  • Express学习笔记(四)——同源和跨域详解
  • (九)图形管线
  • Vue3.5 企业级管理系统实战(十三):TagsView标签栏导航
  • PyQt6实例_A股日数据维护工具_权息数据增量更新线程