【记忆化搜索】矩阵中的最长递增路径

文章目录

  • 329. 矩阵中的最长递增路径
  • 解题思路:暴搜 -> 记忆化搜索

在这里插入图片描述

329. 矩阵中的最长递增路径

329. 矩阵中的最长递增路径

​ 给定一个 m x n 整数矩阵 matrix ,找出其中 最长递增路径 的长度。

​ 对于每个单元格,你可以往上,下,左,右四个方向移动。 你 不能对角线 方向上移动或移动到 边界外(即不允许环绕)。

示例 1:
在这里插入图片描述

输入:matrix = [[9,9,4],[6,6,8],[2,1,1]]
输出:4 
解释:最长递增路径为 [1, 2, 6, 9]。

示例 2:

在这里插入图片描述

输入:matrix = [[3,4,5],[3,2,6],[2,2,1]]
输出:4 
解释:最长递增路径是 [3, 4, 5, 6]。注意不允许在对角线方向上移动。

示例 3:

输入:matrix = [[1]]
输出:1

提示:

  • m == matrix.length
  • n == matrix[i].length
  • 1 <= m, n <= 200
  • 0 <= matrix[i][j] <= 231 - 1

解题思路:暴搜 -> 记忆化搜索

​ 如果抛开什么记忆化搜索的思想来看,这道题和前面遇到的递归问题都是异曲同工之妙,直接用 暴搜 就能解决,我们枚举以每个元素为起点的最长递增路径长度,然后求出其中的最大值即可!

​ 并且 不需要使用 used 数组来进行重复路径判断,因为我们能递归的就是向大元素方向走,此时下一层是不可能返回来的,因为我们加了判断只有元素变大的方向才会去递归!

class Solution {
public:int longestIncreasingPath(vector<vector<int>>& matrix) {// 通过dfs函数获取以每个元素为起点的最长递增路径长度,然后求出其中的最大值即可int ret = 1;for(int i = 0; i < matrix.size(); ++i)for(int j = 0; j < matrix[i].size(); ++j)ret = max(ret, dfs(matrix, i, j));return ret;}int dfs(vector<vector<int>>& matrix, int i, int j){// 递归函数出口if(i < 0 || i == matrix.size() || j < 0 || j == matrix[i].size())return 0;// 递归上下左右方向求出其最长递增路径长度,然后加上当前元素的长度也就是1,求出最大的方向长度int ret = 1;if(i - 1 >= 0 && matrix[i][j] < matrix[i - 1][j])ret = max(ret, dfs(matrix, i - 1, j) + 1);if(j - 1 >= 0 && matrix[i][j] < matrix[i][j - 1])ret = max(ret, dfs(matrix, i, j - 1) + 1);if(i + 1 < matrix.size() && matrix[i][j] < matrix[i + 1][j])ret = max(ret, dfs(matrix, i + 1, j) + 1);if(j + 1 < matrix[i].size() && matrix[i][j] < matrix[i][j + 1])ret = max(ret, dfs(matrix, i, j + 1) + 1);return ret;}
};

​ 很遗憾,这种做法肯定是超时了,因为这是道困难题,但其实本质就是我们之前说的,有大量重复的问题出现,但是我们都没利用起来,所以考虑使用记忆化搜索来优化!

​ 优化的地方非常的简单了,还是三步走,这里不再赘述,比较简单,具体参考代码,只需要关心注释部分即可,如下所示:

class Solution {
private:int memory[201][201] = { 0 }; // 备忘录
public:int longestIncreasingPath(vector<vector<int>>& matrix) {int ret = 1;for(int i = 0; i < matrix.size(); ++i)for(int j = 0; j < matrix[i].size(); ++j)ret = max(ret, dfs(matrix, i, j));return ret;}int dfs(vector<vector<int>>& matrix, int i, int j){// 进入函数前检查一下备忘录if(memory[i][j] != 0)return memory[i][j];if(i < 0 || i == matrix.size() || j < 0 || j == matrix[i].size())return 0;int ret = 1;if(i - 1 >= 0 && matrix[i][j] < matrix[i - 1][j])ret = max(ret, dfs(matrix, i - 1, j) + 1);if(j - 1 >= 0 && matrix[i][j] < matrix[i][j - 1])ret = max(ret, dfs(matrix, i, j - 1) + 1);if(i + 1 < matrix.size() && matrix[i][j] < matrix[i + 1][j])ret = max(ret, dfs(matrix, i + 1, j) + 1);if(j + 1 < matrix[i].size() && matrix[i][j] < matrix[i][j + 1])ret = max(ret, dfs(matrix, i, j + 1) + 1);// 在离开函数之前添加结果到备忘录memory[i][j] = ret;return ret;}
};

在这里插入图片描述

​ 看见没,从超时到这个时间复杂度的优化,是很大的!
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

获取某厂招聘岗位信息

今天方向一个爬虫案例&#xff0c;爬取某厂招聘岗位信息数据&#xff0c;通过程序可以学习pymysql的使用&#xff0c;通过pycharm工具获取数据&#xff0c;并且导入mysql数据库中。 1 导入必要的包 import requests import pymysql2 主体代码 class Baidu(object):def __init…

deepseek R1基本原理解读与系列论文简介

文章目录 前言一、deepseek R1发展史二、deepseek R1简介1、R1简介2、R1成功秘诀3、R1推理模型概念4、R1自我进化与顿悟时刻特点5、不同处理方法比较6、训练流程7、训练阶段8、R1的MLA结构9、R1的MOE结构10、R1的MTP结构11、R1的GRPO结构三、DeepSeek LLM Scaling Open-Source …

数据分析--数据清洗

一、数据清洗的重要性&#xff1a;数据质量决定分析成败 1.1 真实案例警示 电商平台事故&#xff1a;2019年某电商大促期间&#xff0c;因价格数据未清洗导致错误标价&#xff0c;产生3000万元损失医疗数据分析&#xff1a;未清洗的异常血压值&#xff08;如300mmHg&#xff…

【进阶】微服务

微服务架构 服务架构演变过程 单体应用架构 所有的功能都在一个项目中&#xff08;现在使用的就是单体架构&#xff09; 集群架构 把一个单体项目部署多个&#xff0c;使用Nginx进行负载均衡&#xff0c;根据负载均衡策略调用后端服务 不好的地方&#xff1a;有的服务访问…

浏览器开发者工具(F12)查看请求的响应体内容显示”无法加载响应数据: No resource with given identifier found“

背景 复习在 SSM&#xff08;Spring Spring MVC MyBatis&#xff09;框架中&#xff0c;点击登录请求后返回 JSON 格式的数据&#xff0c;出现只有登录失败的请求才有响应值&#xff0c;比如&#xff1a; {success: false, message: “没有此用户”, code: 400} 而成功的请求…

Mybatisplus自定义sql

文章目录 引言流程 引言 mybatisplus最擅长的将where里面的语句给简便化&#xff0c;而不用我们自己写标签来实现条件查询 但是很多公司规范我们将sql写在mapper层中&#xff0c;不能写在service中 而且一些语句查询的不同select count(*) xxx from xxx 也难以用mp来实现 如何…

级联选择器多选动态加载

一.级联展示 注&#xff1a;因为级联选择器这里是动态加载&#xff0c;因此如果上来选中一级就需要加载出后面三级的全部数据&#xff0c;依然会很卡&#xff0c;因此&#xff0c;和产品协商把一二级多选框去掉了&#xff0c;这样也避免了你选择一级不能实现子级被全部选中的问…

MySQL-事务隔离级别

事务有四大特性&#xff08;ACID&#xff09;&#xff1a;原子性&#xff0c;一致性&#xff0c;隔离性和持久性。隔离性一般在事务并发的时候需要保证事务的隔离性&#xff0c;事务并发会出现很多问题&#xff0c;包括脏写&#xff0c;脏读&#xff0c;不可重复读&#xff0c;…

【带你 langchain 双排系列教程】2. langchain 提示词工程应用实践

一、简介 提示词工程在利用 LangChain 与大型语言模型交互中起着关键作用&#xff0c;通过精心设计提示词&#xff0c;可以引导模型生成更准确、更符合预期的输出&#xff0c;从而提升应用的效果和用户体验。 二、基本提示词调用 可以使用 LangChain 提供的 PromptTemplate 来…

git删除本地分支

一、命令方式 1、查看本地分支 git branch 2、切换到一个不删除的分支 git checkout branch_name 3、强制删除分支 git branch -D local_branch_name 二、工具方式 1、选择"Browse references"&#xff0c;右键"Delete branch"

[Computer Vision]实验四:相机标定

目录 一、实验内容 二、实验过程及结果 2.1 实验代码 2.2 实验结果及分析 一、实验内容 了解针孔照相机的相关知识&#xff0c;实现相机标定。&#xff08;可使用提供的棋盘格或自行打印&#xff09; 可视化棋盘格关键点、匹配点数&#xff08;可加ransac&#xff09;输出…

C++笔记之标准库中用于处理迭代器的`std::advance`和`std::distance`

C++笔记之标准库中用于处理迭代器的std::advance和std::distance code review! 文章目录 C++笔记之标准库中用于处理迭代器的`std::advance`和`std::distance`一.`std::advance`函数原型参数说明使用场景示例代码示例 1:移动 `std::vector` 的随机访问迭代器示例 2:移动 `st…

【C++】36.C++IO流

文章目录 1. C语言的输入与输出2. 流是什么3. CIO流3.1 C标准IO流3.2 C文件IO流 4. stringstream的简单介绍 1. C语言的输入与输出 C语言中我们用到的最频繁的输入输出方式就是scanf ()与printf()。 scanf(): 从标准输入设备(键盘)读取数据&#xff0c;并将值存放在变量中。pri…

【抽象代数】1.2. 半群与群

群的定义 群非空集合二元运算性质 定义1. 设 为一个非空集合&#xff0c;上有二元运算&#xff0c;满足结合律&#xff0c;则称或为一个半群。 定义2. 设 为半群&#xff0c;若元素 满足 &#xff0c;则称 为 的左幺元&#xff08;右幺元&#xff1a;&#xff09;&#…

基于ollama+deepseek R1 1.5B本地部署语音交互助手(原创、附代码)

目录 现有的一些功能记录一些过程中遇到的问题安装llama_cpp 1、安装ollama和部署deepseek R12、使用本地部署的deepseek R1模型3、语音识别4、代码实现运行演示 现有的一些功能 1、正常与人沟通&#xff0c;但受限于电脑性能&#xff0c;还存在一定延迟&#xff1b; 2、可以根…

惠普HP Color LaserJet CP1215彩色激光打印机套色不准及套色错位的解决方法

一台惠普HP Color LaserJet CP1215彩色激光打印机出现故障&#xff0c;转印带断裂&#xff0c;于是更换了转印地&#xff0c;当更换完成测试的时候发现这台惠普HP Color LaserJet CP1215彩色激光打印机打印的颜色比较淡且颜色有错位的问题&#xff0c;继续检查机器之后&#xf…

开放签电子签章工具版 2.0 正式发布,构建全场景电子签约能力、满足复杂的签章管理场景

根据近半年开源用户和市场需求反馈&#xff0c;开放签团队推出电子签章工具版2.0版本&#xff0c;主要解决复杂的签约流程集成和电子印章授权管理场景。以API接口对外提供服务和配置一套可视化后台管理系统&#xff0c;可与业务系统无缝集成&#xff0c;用户使用起来毫无“违和…

docker 安装 Rabbitmq 详解

在平常的开发工作中&#xff0c;我们经常会使用到 rabbitmq&#xff0c;rabbitmq 主要可以进行应用解耦、异步通信、流量削峰、负载均衡、消息持久化、死信队列等。比如商城系统&#xff0c;下单后&#xff0c;通过消息队列通知库存系统、积分系统、物流系统等。发送短信时通过…

零基础学yolo系列

1.目标检测算法分类 基于深度学习的主流目标检测算法根据有无候选框生成阶段&#xff0c;分为双阶段目标检 测算法和单阶段目标检测算法两类 双阶段检测模型 将检测问题划分为两个阶段&#xff0c;首先产生候选区域&#xff0c;然后对候选区域分类并对目标位置进行精修&#x…

本智慧监考系统

本智慧监考系统共分为4个部分&#xff0c;分别为&#xff1a;展示层、业务层、算法层和数据库。 本系统的展示层基于Vue.js框架和Ant Design Vue UI框架编写。用户通过浏览器访问前端界面来实现与系统的交互。 业务层是基于SpringBoot框架编写的Java后台服务器。该层负责本系…