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

news2024/9/27 10:43:24

动态规划—64. 最小路径和

  • 前言
  • 题目描述
  • 基本思路
    • 1. 问题定义:
    • 2. 理解问题和递推关系:
    • 3. 解决方法:
      • 3.1. 初始化:
      • 3.2. 边界条件:
      • 3.3. 填充 dp 数组:
      • 3.4. 返回结果:
    • 4. 进一步优化:
    • 5. 小总结:
  • 代码实现
    • Python3代码实现
    • Python 代码解释
    • C++代码实现
    • C++ 代码解释
  • 总结:

前言

给定一个包含非负整数的 m x n 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。

说明:每次只能向下或者向右移动一步。

题目描述

在这里插入图片描述

基本思路

1. 问题定义:

给定一个 m × n m \times n m×n 的网格,每个单元格包含一个非负整数,表示从起点 ( θ , θ ) (\theta, \theta) (θ,θ) 到终点 ( m − 1 , n − 1 ) (m-1, n-1) (m1,n1)的路径的代价。你可以仅向右或向下移动。我们的目标是找到一条路径, 使得路径上的数字之和最小。

2. 理解问题和递推关系:

在这个问题中,我们需要考虑如何从左上角移动到右下角。每个位置的最小路径和可以通过其上方或左方的路径和来计算:

  • 如果当前位置为 ( i , j ) (i, j) (i,j) ,则其最小路径和可以表示为:

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

其中, dp [ i ] [ j ] [i][j] [i][j] 表示到达 ( i , j ) \mathrm{i}, \mathrm{j}) i,j) 的最小路径和。

3. 解决方法:

3.1. 初始化:

我们需要一个二维数组 d p d p dp ,其中 d p [ i ] [ j ] d p[i][j] dp[i][j] 表示到达 ( i , j ) (i, j) (i,j) 的最小路径和。我们可以直接在原始 grid 数组上进行修改,以节省空间。

3.2. 边界条件:

  • 第一行的路径和只能从左边过来, 因此:

d p [ 0 ] [ j ] = d p [ 0 ] [ j − 1 ] + grid ⁡ [ 0 ] [ j ] \mathrm{dp}[0][j]=\mathrm{dp}[0][j-1]+\operatorname{grid}[0][j] dp[0][j]=dp[0][j1]+grid[0][j]

  • 第一列的路径和只能从上边过来, 因此:

d p [ i ] [ 0 ] = d p [ i − 1 ] [ 0 ] + grid ⁡ [ i ] [ 0 ] \mathrm{dp}[i][0]=\mathrm{dp}[i-1][0]+\operatorname{grid}[i][0] dp[i][0]=dp[i1][0]+grid[i][0]

3.3. 填充 dp 数组:

( 1 , 1 ) (1,1) (1,1) 开始填充 dp 数组,直到 ( m − 1 , n − 1 ) (m-1, n-1) (m1,n1)

3.4. 返回结果:

d p [ m − 1 ] [ n − 1 ] dp [m-1][n-1] dp[m1][n1] 即为所求的最小路径和。

4. 进一步优化:

由于计算每个位置的最小路径和仅依赖于上方和左方的位置,我们可以使用一维数组代替二维数组,从而降低空间复杂度。

  • 时间复杂度: O ( m ∗ n ) O(m * n) O(mn) ,需要遍历整个网格。
  • 空间复杂度:使用 O ( n ) O(n) O(n) 的空间来存储当前行的路径和。

5. 小总结:

  • 动态规划: 通过构建一个 dp 数组,记录每个位置的最小路径和,最终得到从起点到终点的最小路径和。
  • 空间优化: 可以用一维数组来存储当前行的最小路径和,进一步降低空间复杂度。

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

代码实现

Python3代码实现

class Solution:
    def minPathSum(self, grid: list[list[int]]) -> int:
        if not grid or not grid[0]:
            return 0
        
        rows, cols = len(grid), len(grid[0])
        
        # 用于存储当前行的最小路径和
        dp = [0] * cols
        
        # 初始化第一行
        for j in range(cols):
            dp[j] = grid[0][j] if j == 0 else dp[j-1] + grid[0][j]
        
        # 遍历每一行
        for i in range(1, rows):
            # 初始化当前行的第一列
            dp[0] += grid[i][0]
            # 遍历当前行
            for j in range(1, cols):
                dp[j] = grid[i][j] + min(dp[j], dp[j-1])
        
        # 返回右下角的最小路径和
        return dp[-1]

Python 代码解释

  • 边界条件:检查输入是否为空。
  • 初始化:创建一维数组 d p dp dp 来存储当前行的最小路径和。
  • 动态规划:先初始化第一行的值,然后逐行更新 d p dp dp 数组中的值,最终返回右下角的值。

C++代码实现

class Solution {
public:
    int minPathSum(vector<vector<int>>& grid) {
        if (grid.empty() || grid[0].empty()) return 0;
        
        int rows = grid.size();
        int cols = grid[0].size();
        
        // 用于存储当前行的最小路径和
        vector<int> dp(cols, 0);
        
        // 初始化第一行
        for (int j = 0; j < cols; ++j) {
            dp[j] = grid[0][j] + (j > 0 ? dp[j - 1] : 0);
        }
        
        // 遍历每一行
        for (int i = 1; i < rows; ++i) {
            dp[0] += grid[i][0];  // 当前行的第一列
            
            // 遍历当前行
            for (int j = 1; j < cols; ++j) {
                dp[j] = grid[i][j] + min(dp[j], dp[j - 1]);
            }
        }
        
        // 返回右下角的最小路径和
        return dp.back();
    }
};

C++ 代码解释

  • 边界条件:检查输入是否为空。
  • 初始化:使用一维数组 dp 来存储当前行的最小路径和。
  • 动态规划:初始化第一行的值,并逐行更新 dp 数组,最终返回右下角的最小路径和。

总结:

  1. 动态规划是解决最小路径和问题的有效方法,通过构建状态转移方程和动态更新路径和来求解最优解。
  2. 空间优化:使用一维数组来降低空间复杂度,使算法在时间和空间上都更高效。

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

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

相关文章

liunx系统虚拟机

https://mirrors.aliyun.com/centos/7.9.2009/isos/x86_64/ 下载地址 DVD版本 安装vm软件12通过vm软件来创建一个虚拟机空间通过vm软件在创建好的虚拟机空间上&#xff0c;安装我们的centos操作系统使用centos你得需要将鼠标点击进入界面中&#xff0c;但是鼠标会消失&#xf…

杨辉三角-C语言

1.问题&#xff1a; 输出杨辉三角。 2.解答&#xff1a; 对有特点的数&#xff08;每行开头和结束的数都是1&#xff09;进行赋值&#xff0c;给中间的数进行赋值&#xff0c;把上面赋值后的二维数组&#xff0c;遍历输出。 3.代码&#xff1a; #include<stdio.h>//头…

基于SSM商铺租赁系统JAVA|VUE|SSM计算机毕业设计源代码+数据库+LW文档+开题报告+答辩稿+部署教+代码讲解

源代码数据库LW文档&#xff08;1万字以上&#xff09;开题报告答辩稿 部署教程代码讲解代码时间修改教程 一、开发工具、运行环境、开发技术 开发工具 1、操作系统&#xff1a;Window操作系统 2、开发工具&#xff1a;IntelliJ IDEA或者Eclipse 3、数据库存储&#xff1a…

使用session来实现验证码发送功能

一、什么是session&#xff1f; Session由服务器创建&#xff0c;并为每一次会话分配一个Session对象。同一个浏览器发起的多次请求&#xff0c;同属于一次会话&#xff08;Session&#xff09;。首次使用到Session时&#xff0c;服务器会自动创建Session&#xff0c;并创建Co…

大觅网之自动化部署(Automated Deployment of Da Mi Network)

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 本人主要分享计算机核心技…

前端大模型入门:Transformer.js 和 Xenova-引领浏览器端的机器学习变革

除了调用别人的api接口使用transformer技术&#xff0c;你是否想过将大模型在浏览器中运行呢&#xff1f;尤其是WebGPU的出现&#xff0c;性能比WebGL高不少&#xff0c;很多小任务真的不再需要在一个中心运行了。 不少同学买课学python了&#xff0c;但我还是在坚持用js尝试&a…

【Linux实践】实验九:Shell流程控制语句

【Linux实践】实验九&#xff1a;Shell流程控制语句 实验目的实验内容实验步骤及结果1. 变量的定义和使用2. 条件3. 运算4. if 语句5. case 语句6. for 语句7. while 语句8. until 语句9. 遍历复制10. 计算平方 实验目的 1、掌握条件判断语句&#xff0c;如if语句、case语句。…

tomcat的安装,管理与配置

目录 Tomcat 服务部署 1.关闭防火墙&#xff0c;将安装 Tomcat 所需软件包上传到虚拟机 2.安装JDK 3.设置JDK环境变量 4.安装启动Tomcat 5.启动tomcat 6.优化tomcat启动速度 Tomcat 服务管理 systemd 管理控制 supervisor 管理控制 Tomcat 虚拟主机配置 1.创建 sun…

EE trade:黄金 999 和黄金 9999 的区别

黄金&#xff0c; 作为一种珍贵的金属&#xff0c; 一直是人们投资和收藏的对象。 在购买黄金时&#xff0c; 您可能会遇到两种纯度的黄金 —— 黄金 999 和黄金 9999。 这两种黄金有什么区别? 消费者应该如何选择呢? 一、 黄金 999 和黄金 9999 的区别 含金量&#xff1a;…

OCR 行驶证识别 离线识别

目录 正页识别 副页识别 全部识别 OCR 行驶证识别 离线识别 正页识别 副页识别 全部识别

C语言实现归并排序(Merge Sort)

目录 一、递归实现归并排序 1. 归并排序的基本步骤 2.动图演示 3.基本思路 4.代码 二、非递归实现 1.部分代码 2.代码分析 修正后代码&#xff1a; 归并过程打印 性能分析 复杂度分析 归并排序是一种高效的排序算法&#xff0c;采用分治法&#xff08;Divide and Con…

中电金信:“源启”金融级数字底座

01方案简介 金融级数字底座是中电金信依托中国电子自主安全计算产业链&#xff0c;采用新一代技术架构&#xff0c;为金融及重点行业打造的数字化新型基础设施。 “源启”面向金融等重点行业场景&#xff0c;依照系统工程方法论&#xff0c;进行全栈技术产品的验证、适配和调…

word2vector训练数据集整理(代码实现)

import math import os import random import torch import dltools from matplotlib import pyplot as plt #读取数据集 def read_ptb():"""将PTB数据集加载到文本行的列表中"""with open(./ptb/ptb.train.txt) as f:raw_text f.read()return…

【深度学习基础模型】双向循环神经网络(Bidirectional Recurrent Neural Networks, BiRNN)详细理解并附实现代码。

【深度学习基础模型】双向循环神经网络&#xff08;Bidirectional Recurrent Neural Networks, BiRNN&#xff09; 【深度学习基础模型】双向循环神经网络&#xff08;Bidirectional Recurrent Neural Networks, BiRNN&#xff09;详细理解并附实现代码。 文章目录 【深度学习…

使用 Llama 3.1 和 Qdrant 构建多语言医疗保健聊天机器人的步骤

长话短说&#xff1a; 准备好深入研究&#xff1a; 矢量存储的复杂性以及如何利用 Qdrant 进行高效数据摄取。掌握 Qdrant 中的集合管理以获得最佳性能。释放上下文感知响应的相似性搜索的潜力。精心设计复杂的 LangChain 工作流程以增强聊天机器人的功能。将革命性的 Llama …

虚幻蓝图Ai随机点移动

主要函数: AI MoveTo 想要AI移动必须要有 导航网格体边界体积 (Nav Mesh Bounds Volume) , 放到地上放大 , 然后按P键 , 可以查看范围 然后创建一个character类 这样连上 AI就会随机运动了 为了AI移动更自然 , 取消使用控制器旋转Yaw 取消角色移动组件 的 使用控制器所需的…

风扇模块(直流5V STM32)

目录 一、介绍 二、传感器原理 1.原理图 2.引脚描述 三、程序设计 main.c文件 fan.h文件 fan.c文件 四、实验效果 五、资料获取 项目分享 一、介绍 直流风扇(Fan)&#xff0c;具有高转速、大风量、低噪音、低能耗和低震动的特点&#xff0c;有DC5V和12V两种型号可供…

【HarmonyOS】Web组件同步与异步数据获取

Web组件交互同步与异步获取数据的方式示例 【html测试文件】src/main/resources/rawfile/Page04.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><script>let isEnvSupported CSS in window &&…

云上攻防 | AWS中的常见 Cognito 配置错误

引言 AWS Cognito 是由亚马逊网络服务&#xff08;AWS&#xff09;提供的全托管服务&#xff0c;旨在简化 Web 和移动应用程序的用户认证和授权过程。它提供了一整套功能来处理用户注册、登录和用户管理&#xff0c;免去了开发人员从头构建这些功能的需求。 尽管本文讨论的攻…

8.11 矢量图层线要素单一符号使用二(箭头)

8.11 矢量图层线要素单一符号使用二(箭头)_qgis箭头-CSDN博客 目录 前言 箭头&#xff08;Arrow&#xff09; QGis设置线符号为箭头(Arrow) 二次开发代码实现 总结 前言 本章介绍矢量图层线要素单一符号中箭头&#xff08;Arrow&#xff09;的使用说明&#xff1a;文章中…