【learning】 单调队列与单调栈用法详解
1、单调栈
单调栈是指一个栈内部的元素具有严格单调性的一种数据结构,分为单调递增栈和单调递减栈。
其具有以下两个性质:
1,满足栈底到栈顶的元素具有严格单调性。
2,满足栈的先进后出特性,越靠近栈顶的元素越后出栈。
元素进栈过程:
对于一个单调递增栈来说,若当前进栈的元素为a,如果a<栈顶元素,则直接将a进栈。
如果a≥栈顶元素,则不断将栈顶元素出栈,直到满足a<栈顶元素。
模拟一个数列构造一个单调递增栈
进栈元素分别为3,4,2,6,4,5,2,3。
图片所示过程即为进栈过程。
实现单调栈STL栈和手写栈均可。
2,单调队列。
单调队列与单调栈及其相似,把单调栈先进后出的性质改为先进先出既可。
元素进队列的过程对于单调递增队列。
对于一个元素a,如果a>队尾元素,那么直接将a扔进队列,如果a≥队尾元素,则将队尾元素出队列,直到满足 a>队尾元素即可。
实现用STL的双端队列即可(我好像一直都是手写的)
由于双端队列即可以在队头操作,也可以在队尾操作,那么这样的性质就弥补了单调栈只能在一边操作的不足。可以使得其左边也有一定的限制。
3,时间复杂度分析
对于每个元素,其有且仅有一次插入,最多出现一次删除,故其时间复杂度为O(n)。
练习:
给你n个数,让你在这n个数中选出连续的m个数(m≤n),使这m个数的极差最小,若存在多个区间使得极差均最小,输出最靠前的区间。
很显然,n≤104时暴力明显可做,n≤106时通过线段树也可做,那如果n去到107呢?
我们考虑用单调队列维护区间[i,i+m−1]的最小值和最大值,以下篇幅以维护最大值举例。
首先,我们把前m个数扔进一个单调递增队列中,在扔进去的同时把这些数所对应的下边也扔进去。显然队头的数字即为区间[1,m]最大的数。
考虑基于[1,m]的数据去更新[2,m+1]的最大值。若第一个数依然存在于队列中(很显然若存在仅可能位于队尾),将这个数删除,然后将第m+1个数插入改单调队列。显然队尾数字即为区间[2,m+1]的最大值。
重复该过程n-m+1次即可,显然时间复杂度为O(n)。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!