单调栈之理解与例题

本文探讨如何利用单调栈解决一维数组问题,如查找第一个比当前元素大的元素的距离,以及在LeetCode中的温度问题。通过栈的插入删除操作(O(1)复杂度),实现高效搜索并保持数组单调性。关键点包括栈的单调性维护和向左遍历的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先它是一个栈,即只能在栈顶插入和删除,其次它是单调的(单调递增or递减),所以插入元素A的时候,需要对比A和栈顶元素B,所有试图破坏这种单调性的元素都要被解决掉。

实际做题的时候,就是利用了这样的特点。

【题目类型总结】

在一维数组中找第一个满足XX条件的数

【题目1】

经典例题,给一个数组,返回一个大小相同的数组。返回的数组的第i个位置的值应当是,对于原数组中的第i个元素,至少往右走多少步,才能遇到一个比自己大的元素(如果之后没有比自己大的元素,或者已经是最后一个元素,则在返回数组的对应位置放上-1)。

简单的例子:

input: 5,3,1,2,4

return: -1 3 1 1 -1

【解析】

一般暴力解法就不说了。题目问往右走遇到一个最近的比自己大的,假设我从左往右遍历,右边的都是没有点亮的地图,一直往右,遇到每个索引,但是都不对(比自己小),我不知道至少找多久(最短距离)才能遇到那个比我大一点的,最差可能走到头也找不到(单身狗哭泣)。那么换一个思路,假设已婚的都是找到了正确的人的,那么他们回首往昔,啊,原来我们遇到的那天就是获得真爱的最短距离。这个比喻有点不恰当,将就看看吧。

那么新的思路出现了,我是一个指针i,从左往右走(遍历一维数组),检查数组i的值,能维持递减的就加到栈顶,如果想破坏这个单调性,就是要增,那么新元素A肯定比栈顶B大,那么,问题从往至少多少步遇到一个的,转换成了,往至少多少步遇到一个

你看,未来不知道(右边没有遍历过),历史却可查(左边的已经存好了),而且拿着新来的A跟栈顶B比较后,如果A>B,B就有了结果,B弹出来,A还是想入栈,就继续跟下一个栈顶元素B1比较,直到符合递减、A能入栈为止。

这就是利用了单调栈的特性,与其说是这种数据结构自身有什么好处,不如说解决问题时用这种思路比较巧妙。也注意到,栈顶元素总比栈底元素先找到结果,找到结果就走了,后进先出LIFO,这也符合栈的特征。

一般来说,处理一个一维数组,我们习惯从左往右遍历,如果一个元素老要跟前面一个元素对比,那么就适合用栈,插入删除的复杂度都是O(1),很方便,而且不用管前一个是什么i;如果类似上面这个题目,要跟前面n个元素对比大小,就用单调栈。

【小结】单调栈的性质
1.单调栈里的元素具有单调性,栈中元素只能是单调递增或者单调递减
2.元素加入栈前,会在栈顶端把破坏栈单调性的元素都删除;
3.使用单调栈可以找到元素向左遍历第一个比它小的元素,也可以找到元素向左遍历第一个比它大的元素。 
(原文链接:https://blog.youkuaiyun.com/liujian20150808/article/details/50752861)

【题目2】

力扣739.每日温度

力扣https://leetcode.cn/problems/daily-temperatures/这个题目跟上面的谷歌算法题基本是一模一样了

【题目3】

这是一个困难题

84. 柱状图中最大的矩形https://leetcode.cn/problems/largest-rectangle-in-histogram/

【题目4】

这也是一个困难题

85. 最大矩形

力扣https://leetcode.cn/problems/maximal-rectangle/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值