【面试经典150 | 动态规划】最小路径和
文章目录
- 写在前面
- Tag
- 题目来源
- 解题思路
- 方法一:动态规划
- 方法二:空间优化
- 写在最后
写在前面
本专栏专注于分析与讲解【面试经典150】算法,两到三天更新一篇文章,欢迎催更……
专栏内容以分析题目为主,并附带一些对于本题涉及到的数据结构等内容进行回顾与总结,文章结构大致如下,部分内容会有增删:
- Tag:介绍本题牵涉到的知识点、数据结构;
- 题目来源:贴上题目的链接,方便大家查找题目并完成练习;
- 题目解读:复述题目(确保自己真的理解题目意思),并强调一些题目重点信息;
- 解题思路:介绍一些解题思路,每种解题思路包括思路讲解、实现代码以及复杂度分析;
- 知识回忆:针对今天介绍的题目中的重点内容、数据结构进行回顾总结。
Tag
【动态规划-空间优化】【数组】
题目来源
64. 最小路径和

解题思路
方法一:动态规划
定义状态
朴素的动态规划方法是定义状态 dp[i][j]
,表示从网格左上角 (0, 0)
位置到 (i, j)
位置的最小路径和。
状态转移
根据题目中 “每次只能向下或者向右移动一步”,可知到达位置 (i, j)
只能从 (i-1, j)
向下移动一步或者从 (i, j-1)
向右一步,因此有转移关系:
d p [ i ] [ j ] = m i n ( d p [ i − 1 ] [ j ] , d p [ i ] [ j − 1 ] ) , i ≥ 1 , j ≥ 1 dp[i][j] = min(dp[i-1][j], dp[i][j-1]), i \ge 1, j \ge 1 dp[i][j]=min(dp[i−1][j],dp[i][j−1]),i≥1,j≥1
base case
dp[0][0] = grid[0][0]
。
对于网格 grid
中的第一行和第一列位置,只能从对应位置的左侧和上方的位置移动一步得到,于是需要进行如下方式的初始化:
// 第一列
for (int i = 1; i < m; ++i)dp[i][0] = dp[i - 1][0] + grid[i][0];// 第一行
for (int j = 1; j < n; ++j) {dp[0][j] = dp[0][j - 1] + grid[0][j];
}
最后返回
dp[m-1][n-1]
表示从网格左上角到网格右下角的最小路径和。
实现代码
class Solution {
public:int minPathSum(vector<vector<int>>& grid) {int m = grid.size(), n = grid[0].size();vector<vector<int>> dp = vector<vector<int>>(m, vector<int>(n));dp[0][0] = grid[0][0];// 对于在第一行或者第一列第一列for (int i = 1; i < m; ++i)dp[i][0] = dp[i - 1][0] + grid[i][0];第一行for (int j = 1; j < n; ++j) {dp[0][j] = dp[0][j - 1] + grid[0][j];}// 对于不在第一行和第一列的元素for (int i = 1; i < m; ++i) {for (int j = 1; j < n; ++j) {dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j];}}return dp[m - 1][n - 1];}
};
复杂度分析
时间复杂度: O ( m n ) O(mn) O(mn), m m m 为网格 grid
的行数, n n n 为网格的列数。
空间复杂度: O ( m n ) O(mn) O(mn)。
方法二:空间优化
方法一中朴素解法的空间复杂度可以进行优化,只需要使用 O ( m i n { m , n } ) O(min\{m, n\}) O(min{m,n}) 的复杂度即可解决。
我们以 示例 1 为例说明,如何使用线性空间解决本题。
网格的行数和列数一样,选择按行来更新最小路径和(选择列也可以),维护一个数组 dp
长度为 3。
初始化 dp = {1, 4, 5}
,dp[0]
表示从位置 (0, 0)
到位置 (0, 0)
的最小路径和;dp[1]
表示从位置 (0, 0)
到位置 (0, 1)
的最小路径和;dp[2]
表示从位置 (0, 0)
到位置 (0, 2)
的最小路径和。
在网格的第一行(从 0 开始数),dp[0]
表示从位置 (0, 0)
到位置 (1, 0)
的最小路径和,因为只能从 (0, 0)
位置到 (1, 0)
位置,所以更新 dp[0] = dp[0] + grid[1][0]
;dp[1]
表示从位置 (0, 0)
到位置 (1, 1)
的最小路径和,因为可以从 (1, 0)
位置向右或者 (0, 1)
位置向下移动到位置 (1, 1)
,所以有 dp[1] = min(dp[0], dp[1]) + grid[i][j]
…
具体实现见如下代码。
实现代码
class Solution {
public:int minPathSum(vector<vector<int>>& grid) {int m = grid.size();int n = grid[0].size();int more = max(m, n);int less = min(m, n);bool rowMore = more == m; // 判断是否是行数大于等于列数vector<int> arr(less); // 以较短维度的长度作为临时空间,比如列数较小int i, j;for (i = 0; i < less; ++i) {// 更新第 0 行的所有列,即初始化if (i == 0) {arr[i] = grid[0][0];}else {arr[i] = arr[i - 1] + (rowMore ? grid[0][i] : grid[i][0]);}}for (i = 1; i < more; ++i) {// 按照行进行更新arr[0] = arr[0] + (rowMore ? grid[i][0] : grid[0][i]); // 更新 i 行 0 列的答案for (j = 1; j < less; ++j) { // 更新 i 行其他列的答案arr[j] = min(arr[j - 1], arr[j]) + (rowMore ? grid[i][j] : grid[j][i]);}}return arr[less-1];}
};
复杂度分析
时间复杂度: O ( m n ) O(mn) O(mn), m m m 为网格 grid
的行数, n n n 为网格的列数。
空间复杂度: O ( m i n { m , n } ) O(min\{m, n\}) O(min{m,n})。
写在最后
如果您发现文章有任何错误或者对文章有任何疑问,欢迎私信博主或者在评论区指出 💬💬💬。
如果大家有更优的时间、空间复杂度的方法,欢迎评论区交流。
最后,感谢您的阅读,如果有所收获的话可以给我点一个 👍 哦。
相关文章:

【面试经典150 | 动态规划】最小路径和
文章目录 写在前面Tag题目来源解题思路方法一:动态规划方法二:空间优化 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法,两到三天更新一篇文章,欢迎催更…… 专栏内容以分析题目为主,并附带一些对于本题…...

生成式AI的情感实验——AI能否产生思想和情感?
机器人能感受到爱吗?这是一个很好的问题,也是困扰了科学家们很多年的科学未解之谜。虽然我们尚未准备好向智能机器赋予情感,但智能机器却已经可以借助生成式人工智能(AI)来帮助我们表达自己的情感。 自然情感表达 AI正…...
力扣贪心算法--第一天
前言 今天是贪心算法的第一天,算法之路重新开始! 内容 之前没了解过贪心算法。 什么是贪心 贪心的本质是选择每一阶段的局部最优,从而达到全局最优。难点就是如何通过局部最优,推出整体最优。 一、455.分发饼干 假设你是一…...

Nginx反向代理和缓存
一、Nginx反向代理 1.调度和代理的区别: 1.调度基于内核层面,代理基于应用层面 2.代理必须实现一手托两家 3.调度不需要监听任何端口,不需要工作任何应用程序,代理需要工作和上游服务器一模一样的进程 4.调度没有并发上限&am…...

支持多元AI场景应用,宁畅“NEX AI Lab”开放试用预约中
3月29日,宁畅在京举行发布会,正式发布“全局智算”战略,并在会上推出战略性新品“AI算力栈”,旨在有效解决大模型产业落地的全周期问题。 据宁畅CTO赵雷介绍,“AI算力栈”集成了宁畅在AI计算领域的软硬件能力ÿ…...

Git 如何合并多个连续的提交
我平常的编程喜欢是写一段代码就提交一次,本地一般不攒代码,生怕本地有什么闪失导致白干。但这样就又导致一个问题:查看历史日志时十分不方便,随便找一段提交可以看到: > git log --oneline 8f06be5 add 12/qemu-h…...

k8s 基础入门
1.namespace k8s中的namespace和docker中namespace是两码事,可以理解为k8s中的namespace是为了多租户,dockers中的namespace是为了网络、资源等隔离 2.deployment kubectl create #新建 kubectl aply #新建 更新 升级: 滚动升级&#x…...

【Python项目】AI动物识别工具
目录 背景 技术简介 系统简介 界面预览 背景 成像技术在全球科技发展中扮演了关键角色。在科学研究领域,拍摄所得的图像成为了一种不可或缺的研究工具。特别是在生态学与动物学研究中,鉴于地球的广阔地域和多样的气候条件,利用图像技术捕…...
逻辑回归(Logistic Regression)详解
逻辑回归是一种用于解决二分类问题的统计方法,它通过构建一个模型来预测某个事件的概率。 以下是逻辑回归的一些关键要点: 适用场景:逻辑回归特别适合于处理二分类问题,即两个类别的分类问题,例如判断一封邮件是否为…...
.vimrc文件的语句语法
本文结构: a、简介 b、详细解释其中的一些常见语句和语法。 a、.vimrc 文件是 Vim 编辑器用于配置用户设置和自定义行为的文件。当 Vim 启动时,它会读取 .vimrc 文件中的命令和设置,并根据这些指令来配置编辑器的行为。 b、.vimrc 文件中…...
c语言之函数指针作形参
在一些c语言的大工程中,会在定义的函数中,把一些其他函数指针作为本函数形参。 函数指针作形参的例子 代码如下: #include<stdio.h> int max(int a,int b) { return(a>b?a:b); } int min(int a,int b) { return(a<b?a:b); } i…...
python文件的读取操作
打开文件 fopen("F:/python/helloworld/测试.txt","r",encoding"UTF-8")读取文件 print(f"读取10个字节的结果{f.read(10)}") print(f"读取全部字节的结果{f.read()}") linesf.readlines() print(f"{lines}")读…...

查看并设定【网络适配器】的优先级(跃点数)
目录 前言: 1.查看所有的适配器 2.修改优先级(需要以管理员身份运行) 跃点数(InterfaceMetric ) DHCP 3.修改后的效果 pwoerShell 再次运行之前的程序 4.其他 参考 网络适配器1,8相关知识介绍1 …...

深入理解 Hadoop 上的 Hive 查询执行流程
在 Hadoop 生态系统中,Hive 是一个重要的分支,它构建在 Hadoop 之上,提供了一个开源的数据仓库系统。它的主要功能是查询和分析存储在 Hadoop 文件中的大型数据集,包括结构化和半结构化数据。Hive 在数据查询、分析和汇总方面发挥…...

JS封装网页进入/退出全屏功能,兼容各大主流浏览器
1、演示 2、封装进入全屏函数 mozRequestFullScreen:兼容Firefox webkitRequestFullscreen:兼容 Chrome、Safari、Opera msRequestFullscreen:兼容:IE/Edge const enter () > {const element document.documentElementif (el…...
el-table的复选框勾选整行变色
要实现el-table的复选框勾选整行变色,你可以使用element-ui提供的row-class-name属性结合scoped slot来完成。 首先,你需要为el-table组件添加 row-class-name 属性,并给它绑定一个方法。在这个方法中,你可以根据你的业务逻辑来判…...
一步一步写线程之八线程池的完善之二数据结构封装
一、数据容器 在前面分析过,不管是线程任务的封装还是同步数据队列的封装,都是需要一个数据结构的。一用来说,如果没有什么特殊的原因,开发者都是使用STL中数据结构。比如前面经常见到的std::queue,std::deque,std::vector,std::…...

go连接数据库(原生)
根据官网文档 Go Wiki: SQL Database Drivers - The Go Programming Language 可以看到go可以连接的关系型数据库 常用的关系型数据库基本上都支持,下面以mysql为例 下载mysql驱动 打开上面的mysql链接 GitHub - go-sql-driver/mysql: Go MySQL Driver i…...

【C语言】2048小游戏【附源码】
欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 一、游戏描述: 2048是一款数字益智类游戏,玩家需要使用键盘控制数字方块的移动,合并相同数字的方块,最终达到数字方块上出现“2048”的目标。 每次移动操作,所…...

部署项目遇到的各种问题总结
文章目录 前言一、后端问题 jar包运行出现错误宝塔面板使用jdk17二、数据库问题 版本问题三、前端问题 连不上后端总结 前言 在做完项目之后,为了让别人访问到自己的网站,就需要部署前端后端以及数据库,但是在部署的过程中出现了各种问题和困…...
<6>-MySQL表的增删查改
目录 一,create(创建表) 二,retrieve(查询表) 1,select列 2,where条件 三,update(更新表) 四,delete(删除表…...

工业安全零事故的智能守护者:一体化AI智能安防平台
前言: 通过AI视觉技术,为船厂提供全面的安全监控解决方案,涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面,能够实现对应负责人反馈机制,并最终实现数据的统计报表。提升船厂…...
Spring Boot 实现流式响应(兼容 2.7.x)
在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...
动态 Web 开发技术入门篇
一、HTTP 协议核心 1.1 HTTP 基础 协议全称 :HyperText Transfer Protocol(超文本传输协议) 默认端口 :HTTP 使用 80 端口,HTTPS 使用 443 端口。 请求方法 : GET :用于获取资源,…...

免费数学几何作图web平台
光锐软件免费数学工具,maths,数学制图,数学作图,几何作图,几何,AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...
比较数据迁移后MySQL数据库和OceanBase数据仓库中的表
设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...

STM32---外部32.768K晶振(LSE)无法起振问题
晶振是否起振主要就检查两个1、晶振与MCU是否兼容;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容(CL)与匹配电容(CL1、CL2)的关系 2. 如何选择 CL1 和 CL…...