【LeetCode】动态规划—931. 下降路径最小和(附完整Python/C++代码)

动态规划—931. 下降路径最小和

  • 前言
  • 题目描述
  • 基本思路
    • 1. 问题定义
    • 2. 理解问题和递推关系
    • 3. 解决方法
      • 3.1 动态规划方法
      • 3.2 空间优化的动态规划
    • 4. 进一步优化
      • 4.1 空间复杂度优化
    • 5. 小总结
  • 代码实现
    • Python3代码实现
    • Python 代码解释
    • C++代码实现
    • C++ 代码解释
  • 总结:

前言

在算法的学习中,动态规划是一个至关重要的思想,特别是在解决最优路径问题时,动态规划能够提供一种高效且直观的解决方案。最小下降路径和问题就是这样一个经典的动态规划问题。它要求我们在一个二维矩阵中,从第一行的任意一个元素开始,每次只能向下、左下、右下移动,找到通往最后一行的最小路径和。这类问题不仅在理论上具有挑战性,同时也在实际生活中的路径规划、图像处理等领域有广泛应用。

本文将通过深入剖析最小下降路径和问题,帮助你掌握该类问题的动态规划思路。我们将从问题的定义和递推公式出发,逐步推导解决方法,并提供优化空间复杂度的技巧。同时,本文提供了详细的 Python 和 C++ 代码实现,并对代码进行了逐行解释。无论你是初学者还是有经验的开发者,都可以从本文中获得有益的启发,并加深对动态规划的理解。

希望本文能为你提供清晰的思路,帮助你在解决类似问题时更加得心应手。

题目描述

在这里插入图片描述

基本思路

1. 问题定义

给定一个 n n n * n n n 的方形矩阵 matrix,每个位置都包含一个整数。你可以从矩阵的第一行任何一个元素开始,并逐步向下移动到达最后一行。每次移动时,你只能移动到下一行的同一列、左上方一列或右上方一列的位置。要求你找到从第一行移动到最后一行的最小路径和。

2. 理解问题和递推关系

  • 问题的核心是寻找一条从第一行到最后一行的最小路径和,每次移动只能向下、左下或右下移动。
  • 对于任意位置 ( i , j ) (i, j) (i,j) 的最小路径和 d p [ i ] [ j ] d p[i][j] dp[i][j] ,它可以通过前一行的三个可能位置中的最小值来更新:

d p [ i ] [ j ] = matrix ⁡ [ i ] [ j ] + min ⁡ ( d p [ i − 1 ] [ j ] , d p [ i − 1 ] [ j − 1 ] , d p [ i − 1 ] [ j + 1 ] ) d p[i][j]=\operatorname{matrix}[i][j]+\min (d p[i-1][j], d p[i-1][j-1], d p[i-1][j+1]) dp[i][j]=matrix[i][j]+min(dp[i1][j],dp[i1][j1],dp[i1][j+1])

  • 边界处理:如果位置 ( i − 1 , j − 1 ) (i-1, j-1) (i1,j1) 或 ( i − 1 , j + 1 ) i-1, j+1) i1,j+1) 越界, 忽略该位置。

3. 解决方法

3.1 动态规划方法

  1. 创建一个二维数组 d p d p dp ,其中 d p [ i ] [ j ] d p[i][j] dp[i][j] 表示从第一行到达位置 ( i , j ) (i, j) (i,j) 的最小路径和。
  2. 初始化 d p d p dp 的第一行,直接等于 matrix 的第一行。
  3. 从第二行开始,依次计算每个位置的最小路径和,利用前一行的 dp 值填充当前行的 dp 。
  4. 最终结果为 d p [ n − 1 ] d p[n-1] dp[n1] 中的最小值, 即从第一行到达最后一行的最小路径和。

3.2 空间优化的动态规划

  • 可以使用一维数组代替二维数组 d p d p dp 来节省空间。只需要记录当前行和上一行的最小路径和。

4. 进一步优化

4.1 空间复杂度优化

  • 可以仅使用一维数组保存前一行的最小路径和,逐行更新,降低空间复杂度为 O ( n ) O(n) O(n)

5. 小总结

  • 动态规划是解决此类问题的核心。我们可以通过递推公式求解每一行的最小路径和,逐步构建出全局的最优解。
  • 优化后的空间复杂度可以从 O ( n ∧ 2 ) O\left(n^{\wedge} 2\right) O(n2) 降低到 O ( n ) O(n) O(n) ,这对于大规模矩阵的计算更加高效。

以上就是下降路径最小和问题的基本思路。

代码实现

Python3代码实现

class Solution:def minFallingPathSum(self, matrix: list[list[int]]) -> int:n = len(matrix)# 使用动态规划填充dp数组,第一行等于matrix的第一行dp = matrix[0][:]# 从第二行开始for i in range(1, n):# 创建一个临时数组存储当前行的最小路径和new_dp = [0] * nfor j in range(n):# 当前元素可以从上方、左上方或右上方到达min_prev = dp[j]if j > 0:min_prev = min(min_prev, dp[j - 1])if j < n - 1:min_prev = min(min_prev, dp[j + 1])# 更新当前元素的最小路径和new_dp[j] = matrix[i][j] + min_prevdp = new_dp# 返回最后一行的最小路径和return min(dp)

Python 代码解释

  • 初始化:创建 dp 数组,用于存储前一行的最小路径和。初始化为 matrix 第一行的值。
  • 动态规划递推:从第二行开始,逐行更新 dp。每个位置 (i, j) 的最小路径和通过前一行的三个可能位置 ( d p [ i − 1 ] [ j ] 、 d p [ i − 1 ] [ j − 1 ] 、 d p [ i − 1 ] [ j + 1 ] ) (dp[i-1][j]、dp[i-1][j-1]、dp[i-1][j+1]) dp[i1][j]dp[i1][j1]dp[i1][j+1]中最小的值来更新。
  • 返回结果:最终返回 dp 数组中的最小值,即最后一行的最小路径和。

C++代码实现

class Solution {
public:int minFallingPathSum(vector<vector<int>>& matrix) {int n = matrix.size();// 使用dp数组存储前一行的最小路径和vector<int> dp(matrix[0]);// 从第二行开始for (int i = 1; i < n; ++i) {vector<int> new_dp(n, 0);  // 当前行的dp数组for (int j = 0; j < n; ++j) {int min_prev = dp[j];if (j > 0) min_prev = min(min_prev, dp[j - 1]);if (j < n - 1) min_prev = min(min_prev, dp[j + 1]);new_dp[j] = matrix[i][j] + min_prev;}dp = new_dp;  // 更新dp为当前行的最小路径和}// 返回最后一行的最小路径和return *min_element(dp.begin(), dp.end());}
};

C++ 代码解释

  • 初始化:创建 dp 数组,保存前一行的最小路径和,初始值为 matrix 的第一行。
  • 动态规划递推:从第二行开始,逐行计算每个位置的最小路径和,通过前一行的三个可能位置的最小值更新当前行。
  • 返回结果:遍历最后一行的 dp 数组,返回其中的最小值,即最小路径和。

总结:

  • 时间复杂度:无论是 P y t h o n Python Python 代码还是 C + + C++ C++ 代码,时间复杂度都是 O ( n ∧ 2 ) O\left(n^{\wedge} 2\right) O(n2) ,因为我们需要遍历矩阵的每个元素。
  • 空间复杂度:通过使用一维数组来代替二维 d p d p dp 数组,空间复杂度优化为 O ( n ) O(n) O(n) ,显著减少了内存占用。
  • 动态规划思想:该问题可以通过动态规划思想轻松解决,核心在于计算毎一行的最小路径和,并逐步累积到最后一行。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1550356.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

MWORKS.Sysplorer 2024b重磅推出同元基础库

一、引言 MWORKS.Sysplorer 是多领域建模与仿真平台&#xff0c;集成了Modelica标准库。该库由Modelica协会开发&#xff0c;是一款开源的通用基础模型库&#xff0c;支持机电、流体、控制等多个专业领域的建模与仿真。随着Modelica标准库的不断发展与更新&#xff0c;目前最新…

【设计模式-中介者模式】

定义 中介者模式&#xff08;Mediator Pattern&#xff09;是一种行为设计模式&#xff0c;通过引入一个中介者对象&#xff0c;来降低多个对象之间的直接交互&#xff0c;从而减少它们之间的耦合度。中介者充当不同对象之间的协调者&#xff0c;使得对象之间的通信变得简单且…

双十一不被割韭菜!2024双十一总结五款好物分享!

每年双十一购物节来临之际&#xff0c;随着心仪商品缓缓填满购物车&#xff0c;那份对即将收获的期待与内心的喜悦&#xff0c;自然而然地溢于言表。在这个优惠纷呈的购物盛宴中&#xff0c;寻找那些既符合个人需求又具备高品质的宝贝&#xff0c;成为了一项既充满乐趣又考验眼…

大语言模型在构建UNSPSC 分类数据中的应用

UNSPSC 是联合国标准产品和服务代码。UNSPSC由联合国开发计划署&#xff08;UNDP&#xff09;和Dun & Bradstreet公司&#xff08;D & B&#xff09;于1998年联合制定&#xff0c;自2003年以来一直由GS1 US管理。GS1 US 将在 2024 年底前将 UNSPSC 的管理权移交给 UNDP…

胤娲科技:揭秘AI记忆宫殿—LLM如何用动画玩转乔丹打篮球的秘密

当AI遇上“乔丹打篮球”&#xff0c;真相竟然藏在动画里&#xff1f; 想象一下&#xff0c;你向一位AI大模型轻声询问&#xff1a;“迈克尔・乔丹从事的体育运动是……”几乎在瞬间&#xff0c;它就自信满满地回答&#xff1a;“篮球&#xff01;” 这一刻&#xff0c;你是否曾…

跨境电商新风尚:一键解锁中国电商的全球代购奇迹

在全球化日益加深的今天&#xff0c;跨境电商成为了连接中国与世界消费者的桥梁&#xff0c;尤其是为国外客户代购中国电商商品的服务&#xff0c;正以一种前所未有的方式改变着国际购物体验。本文将深入探讨跨境电商代购系统的基本功能&#xff0c;揭示其背后的技术魅力与商业…

C#绘制动态曲线

前言 用于实时显示数据动态曲线&#xff0c;比如&#xff1a;SOC。 //用于绘制动态曲线&#xff0c;可置于定时函数中&#xff0c;定时更新数据曲线 void DrawSocGraph() {double f (double)MainForm.readData[12]; //display datachart1.Series[0].Points.Add(f);if (ch…

如何在云端地球建模云平台利用无人机航拍照片进行三维建模?

第一步&#xff1a;导入照片 进入云端地球工作台&#xff0c;选择【场景建模】将航拍的照片组导入。 输入模型名称&#xff08;若无则无法上传&#xff09;&#xff0c;点击【上传】&#xff0c;将照片上传到云端服务器。 第二步&#xff1a;创建任务 上传成功后点击开始处理…

生成模型常见的条件融合方式

生成模型常见的条件融合方式 目前生成模型主要有4中常见的条件融合方式以实现可控生成&#xff1a;条件归一化层&#xff0c;Decoupled Cross-Attention&#xff0c;self-attention层进行融合&#xff0c;特征值逐元素求和。本文首先介绍下各种方法现&#xff0c;然后进行总结&…

华为云LTS日志上报至观测云最佳实践

华为云LTS简介 华为云云日志服务&#xff08;Log Tank Service&#xff0c;简称 LTS&#xff09;&#xff0c;用于收集来自主机和云服务的日志数据&#xff0c;通过海量日志数据的分析与处理&#xff0c;可以将云服务和应用程序的可用性和性能最大化&#xff0c;为您提供实时、…

三维立体自然资源“一张图”

随着信息技术的发展&#xff0c;自然资源管理迎来了新的机遇与挑战。在众多技术中&#xff0c;“三维立体自然资源‘一张图’”的概念尤为引人注目。它不仅代表了地理信息科学领域的最新成果&#xff0c;也为自然资源的有效管理和可持续利用提供了强有力的支持。本文将探讨这一…

同元软控受邀出席2024第四届国际自主无人系统大会

9月19-21日&#xff0c;2024第四届国际自主无人系统大会在沈阳召开。辽宁省副省长高涛&#xff0c;沈阳市委副书记、市长吕志成出席并致辞。 本届大会由中国科学院沈阳自动化研究所、国防科技大学、西北工业大学、南京理工大学、中国航空学会共同主办&#xff0c;以“自主无人…

Webpack 特性探讨:CDN、分包、Tree Shaking 与热更新

文章目录 前言包准备CDN 集成代码分包Tree Shaking原理实现条件&#xff1a;解决 treeShaking 无效方案&#xff1a;示例代码&#xff1a; 热更新&#xff08;HMR&#xff09; 前言 Webpack 作为现代前端开发中的核心构建工具&#xff0c;提供了丰富的特性来帮助开发者优化和打…

【sw2024】solidworks2024双击setup.exe无反应管理员运行也没反应解决方法

第一步 官网下载xxclean&#xff0c;打开xxclean最新版本&#xff0c;登录。官网xxclean.com或者自己浏览器搜。 第二步 点击扩展功能&#xff0c;点击 运行sw2024安装程序无反应 右边的开始 第三步 进度百分之百之后去双击setup就有界面了。

unix中的exec族函数介绍

一、前言 本文将介绍unix中exec族函数&#xff0c;包括其作用以及使用方法。当一个进程调用fork函数创建一个新进程后&#xff0c;新进程可以直接执行原本正文段的其他内容&#xff0c;但更多时候&#xff0c;我们在一个进程中调用fork创建新的进程后&#xff0c;希望新进程能…

ApiSix 插件开发

版本 3.0.1 创建插件目录和文件 cd ./example/ mkdir -p apisix/plugins cd apisix/plugins touch my_plugin.lua结构如下&#xff1a; 编写脚本 local core require("apisix.core")local plugin_name "my_plugin"local schema {type "obje…

MySQL约束:外键约束

下面先创建两张表用来作为实验样例 1.创建dept表 create table dept(id int auto_increment comment ID primary key,name varchar(50) not null comment 部门名称 ) comment 部门表;INSERT INTO dept (id, name) VALUES (1, 研发部), (2, 市场部), (3, 财务部), (4, 销售部…

基于服务网格的集群访问控制

随着容器化、云原生等概念的火热&#xff0c;越来越多的应用都开始选择支持云原生部署&#xff0c;但是对于大型企业应用来说&#xff0c;各种为服务的拆分会导致集群运维的压力越来越大&#xff0c;尤其是服务之间的安全通信至关重要。 在容器化集群中&#xff0c;传统的基于…

同元软控参展2024超临界二氧化碳动力循环与多能互补系统国际会议

9月20-23日&#xff0c;2024超临界二氧化碳动力循环与多能互补系统国际会议&#xff08;简称ICSPC2024&#xff09;在上海召开。会议由中国科学院工程热物理研究所、中国工程热物理学会主办&#xff0c;华北电力大学、西安热工研究院有限公司为联合主办单位。同元软控携核反应堆…

7.3树形查找

7.3.1二叉排序树 1.定义 目的:提供查找删除,插入关键字的速度 二叉排序树的特性: 左子树<根节点<右子树左右字数也分别是一棵二叉树 对二叉排序树进行中序遍历,可以得到一个递增的有序序列 2.二叉排序树的查找 查找从根节点开始,沿分支逐层向下比较的过程 二叉排序…