数据结构——单调栈

前导:

        队列,栈,前面的链接是对普通的栈,和普通的队列的一个讲解,如果没有对普通的栈和队列不了解的小伙伴可以先看看前面链接中的讲解;

        什么是单调,一个序列呈递增或者递减,并且没有一个位置违反了这个递增递减的性质,那么这个序列就算单调序列;

单调栈

        咱么先讲单调栈,什么是单调栈,知名知其意,栈里面的元素应该是单调的;而单调栈的作用就是去维护它里面的元素成单调性,例如它可以用来找某个元素左右侧最近比他大比他小的元素的位置;下面直接来图片演示他是如何操作的:

       初始状态       开始入栈:

        一直入栈直到索引3时: 

        现在继续入栈,到索引5,如果直接入栈索引5又破坏了单调性,那么又需要出栈元素:

        最后通过,这样的操作之后,最终结果为:

单调栈的作用

       单调栈的主要作用是在处理数据序列中,帮助快速解决一些需要维护单调性的问题,例如:
        1. 寻找下一个更大元素或更小元素:单调栈可以用于查找某个元素右侧或左侧的第一个比它大或小的元素,这在解决一些问题中非常有用,比如上图中索引2位置的92右边最近比他小的就是索引3的65;

        2.解决其他需要维护单调性的问题:除了上述示例,单调栈还可用于解决其他需要维护单调性的问题,如找到数组中连续子数组的最大或最小值。

        等等,这些需要思考问题的过程中来进行转换,而不是死记硬背,这个就像数学一样,你背下了公式,但是你也不一定会做题,所以需要多做题进行来加深自己的逻辑框架。

例题:

        这个数据结构直接去实现没有太大的作用,所以选择一个题目进行来讲解:

        leetcode 84

        让你求最大矩形的面积,而这个问题就是进行枚举,然后求每一个矩形的面积,而求每一个矩形的面积如何求,那么这里就可以用到单调栈;

        如何求该位置的面积:

        

        初始化,单调栈:

        然后可能会有疑问,觉得现在还是没有头绪,没关系往后看:

        然后继续上面的操作:

        而从数组右边开始,就是这样:

        同样的维护单调栈的性质,和左边遍历数组的操作一样,我就不画图了;

        然后一直进行这样维护单调栈的性质,最终得到结果:

        然后通过两个数组得到,每个位置可以得到的最大的矩形面积,然后再枚举一次数组,进行得到最终最大矩形面积:

        

        

        最终找到题目要求的答案;

int largestRectangleArea(int* heights, int heightsSize){int n = heightsSize;int l[n + 5], r[n + 5];//创建l,r数组int s[n + 5];//创建栈memset(s, 0, sizeof(s));//初始化清空栈int top = -1;//top = 0,-1都可以,只是有些条件需要变化一下,这是不影响的s[++top] = -1;//入栈虚拟位置for (int i = 0; i < n; i++) {while (top > 0 && heights[s[top]] >= heights[i]) top--;//top > 0,虚拟位置一直存在栈中,就不用再创建新数组来添加虚拟位置,相当于虚拟位置的高度-1在心中l[i] = s[top]; //将最近做左边比i位置高度矮的最近位置记录下来s[++top] = i; //入栈i,现在的栈已经维护到入栈i位置一样成单调递增}top = -1;//初始化栈顶指针s[++top] = n;//将虚拟位置入栈for (int i = n - 1; i >= 0; i--) {//和上面的逻辑一样,就不解释了while (top > 0  && heights[s[top]] >= heights[i]) top--;r[i] = s[top];s[++top] = i;}int ans = 0;for (int i = 0; i < n; i++) {int sum = heights[i] * (r[i] - l[i] - 1);//枚举找每个位置的最大面积ans = fmax(sum, ans);//记录最大矩形面积}return ans;
}

 单调队列明天会出文章续上,这篇已经花了4个小时了,觉得有用给作者一个赞吧;

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

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

相关文章

Spring-Kafka生产者源码分析

文章目录 概要初始化消息发送小结 概要 本文主要概括Spring Kafka生产者发送消息的主流程 代码准备&#xff1a; SpringBoot项目中maven填加以下依赖 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent&…

Flink提交jar出现错误RestHandlerException: No jobs included in application.

今天打包一个flink的maven工程为jar&#xff0c;通过flink webUI提交&#xff0c;发现居然报错。 如上图所示&#xff0c;提示错误为&#xff1a; Server Response Message: org.apache.flink.runtime.rest.handler.RestHandlerException: No jobs included in application. …

Java 线程池概念总结(thread pool)

一、池化思想的应用 池化思想是一种常见软件设计和优化技术。以下是几个常见池化思想应用场景&#xff1a; 线程池&#xff1a;线程池是池化思想一个典型应用。通过预先创建一组线程并将它们置于就绪状态&#xff0c;以复用线程减少线程创建和销毁的开销&#xff0c;并提高系统…

Nginx特性应用及载装

Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器。其特点是占有内存少&#xff0c;并发能力强&#xff0c;事实上nginx的并发能力在同类型的网页服务器中表现较好&#xff0c;中国大陆使用nginx的网站有&#xff1a;网易、腾讯、阿里等。 …

MyBatis-Plus —— 初窥门径

前言 在前面的文章中荔枝梳理了MyBatis及相关的操作&#xff0c;作为MyBatis的增强工具&#xff0c;MyBatis-Plus无需再在xml中写sql语句&#xff0c;在这篇文章中荔枝将梳理MyBatis-Plus的基础知识并基于SpringBoot梳理MyBatis-Plus给出的两个接口&#xff1a;BaseMapper和ISe…

对象模型和this指针(个人学习笔记黑马学习)

1、成员变量和成员函数 #include <iostream> using namespace std; #include <string>//成员变量和成员函数分开存储class Person {int m_A;//非静态成员变量 属于类的对象上的static int m_B;//静态成员变量 不属于类的对象上void func() {} //非静态成员函数 不…

供应链 | 顶会CIKM论文精读:面向大规模三维装箱问题的数据驱动树形搜索算法

论文解读&#xff1a;丁建辉&#xff0c;李明哲&#xff0c;赵艳蓉&#xff0c;孙楚天 编者按 本次解读的文章发表于CCF-B类会议30th ACM International Conference on Information and Knowledge Management。摘要总结如下&#xff1a; 3维装箱问题&#xff08;3D-BPP&#…

Redis的缓存穿透,缓存击穿,缓存雪崩

1. 缓存穿透 什么是缓存穿透&#xff1f; 缓存穿透说简单点就是大量请求的 key 是不合理的&#xff0c;根本不存在于缓存中&#xff0c;也不存在于数据库中 。这就导致这些请求直接到了数据库上&#xff0c;根本没有经过缓存这一层&#xff0c;对数据库造成了巨大的压力&…

雪花算法生成id分析与实践

目录 1 什么是雪花算法&#xff1f; 结构 优点 缺点 2 在java中使用 使用注意&#xff1a; 测试代码 效果 1 什么是雪花算法&#xff1f; witter的雪花算法&#xff08;Snowflake Algorithm&#xff09;。雪花ID是一种分布式唯一ID生成算法&#xff0c;旨在解决分布式…

数学建模-点评笔记 9月3日

1.摘要&#xff1a;关键方法和结论&#xff08;精炼的语言&#xff09;要说明&#xff0c;方法的合理性和意义也可以说明。 评委先通过摘要筛选&#xff08;第一轮&#xff09; 2.时间序列找异常值除了3西格玛还有针对时间序列更合适寻找的方法 3.模型的优缺点要写的详细一点…

世微AP9234 升压型DC/DC LED恒流驱动

描述 AP9234是一款由基准电压源、振荡电路、误差放大电路、相位补偿电路、电流限制电路等构成的CMOS升压型DC/DC LED驱动。由于内置了低导通电阻的增强型N沟道功率MOSFET&#xff0c;因此适用于需要高效率、高输出电流的应用电路。另外&#xff0c;可通过在VSENSE端子连接电流…

754. 到达终点数字

754. 到达终点数字 原题链接&#xff1a;完成情况&#xff1a;解题思路&#xff1a;参考代码&#xff1a; 原题链接&#xff1a; 754. 到达终点数字 https://leetcode.cn/problems/reach-a-number/description/ 完成情况&#xff1a; 解题思路&#xff1a; 牛顿莱布尼茨梯…

SWAT-MODFLOW地表水与地下水耦合

耦合模型被应用到很多科学和工程领域来改善模型的性能、效率和结果&#xff0c;SWAT作为一个地表水模型可以较好的模拟主要的水文过程&#xff0c;包括地表径流、降水、蒸发、风速、温度、渗流、侧向径流等&#xff0c;但是对于地下水部分的模拟相对粗糙&#xff0c;考虑到SWAT…

ConsoleApplication815项目(直接加载+VEH Hook Load)

上线图 ConsoleApplication815.cpp #include <iostream> #include<Windows.h> #include "detours.h" #include "detver.h" #pragma comment(lib,"detours.lib")#pragma warning(disable:4996)LPVOID Beacon_address; SIZE_T Beacon…

敏捷开发、V模型开发、瀑布模型

在软件开发领域&#xff0c;敏捷开发和V模型开发是两种主要的开发方法。它们之间的差异主要体现在开发过程的结构和组织方式上。在以下讨论中&#xff0c;我们将深入探讨这两种方法的特点和差异。 敏捷开发 敏捷开发是一种迭代和增量的软件开发方法&#xff0c;它强调灵活性和…

rz命令无法正常使用?

使用rz命令上传文件时出现如下问题&#xff1a; 这里用的是mobaxterm终端 改用xshell,secureCRT即可正常使用&#xff1a;

vscode调教配置:快捷修复和格式化代码

配置vscode快捷键&#xff0c;让你像使用idea一样使用vscode&#xff0c;我们最常用的两个功能就是格式化代码和快捷修复&#xff0c;所以这里修改一下快捷修复和格式化代码的快捷键。 在设置中&#xff0c;找到快捷键配置&#xff1a; 然后搜索&#xff1a;快捷修复 在快捷键…

Mqtt学习笔记--交叉编译移植(1)

简述 Mqtt目前在物联网行业的应用比较多&#xff0c;mqtt属于应用层的一个中间件&#xff0c;这个中间件实现消息的订阅发布机制。网上介绍Mqtt的实现原来的比较多&#xff0c;这里不细介绍。 其实在我们之前的产品中&#xff0c;自己也开发的有类似的中间件&#xff0c;除了具…

ORB-SLAM2算法12之单目初始化Initializer

文章目录 0 引言1 单目初始化Initializer1.1 构造函数1.2 成员函数1.2.1 Initialize1.2.2 FindHomography1.2.3 FindFundamental1.2.4 ReconstructH1.2.5 ReconstructF 2 总结 0 引言 ORB-SLAM2算法7详细了解了System主类和多线程、ORB-SLAM2学习笔记8详细了解了图像特征点提取…

每日一题 1921. 消灭怪物的最大数量

难度&#xff1a;中等 思路&#xff1a; 已知速度和距离&#xff0c;可求时间必定先消灭时间最短的怪物求得时间数组排序&#xff0c;只要在第 i 秒时&#xff0c;time[i] > i &#xff0c;那么就可以消灭第 i 个怪物 代码&#xff1a; class Solution:def eliminateMax…