单调栈结构

原始问题:
给你一个数组,找出数组中 每个数左边离它最近的 比它大的数 和右边离它最近的 比它大的数
要求算法复杂度:O(N)

例子:
一个数组:
在这里插入图片描述
对于0位置,其左面的 离它最近的 比自己大的数,没有
其右面的 离它最近的 比自己大的数 5

前四个位置的数,每个数左边离它最近的 比它大的数 和右边离它最近的 比它大的数 总结如下:
在这里插入图片描述
暴力解:
遍历到某个位置的时候,左边遍历找 刚刚 比其大的值,然后右边遍历找 刚刚 比其大的值。
但是复杂度O(N²)??

优化解:
准备一个栈,
栈:先进后出(像压子弹一样)

要求每次元素进栈后要维持栈中从栈底到栈顶元素值是从大到小排列的约定。将数组中的元素依次进栈,如果某次元素进栈后会违反了上述的约定(即该进栈元素比栈顶元素大),就先弹出栈顶元素,并记录该栈顶元素的信息:
即,类似于双端队列

例子:
在这里插入图片描述
02.32.07

当下一个3位置上的数6,大于栈中所有的数

所以,2位置上 右面最大的数 是6
2位置上 左面最大的数 是1位置上的数 4

当此数无法落在当前栈顶,当前栈顶要弹出的时候,开始生成

谁让它弹出,谁就是右边 比它大的数!

即,弹出3时,生成
在这里插入图片描述
下一步,弹出4时,生成:
在这里插入图片描述
下一步,弹出5时,生成:
(5下面没有数)
在这里插入图片描述
在弹出数 的过程中,生成了这些信息:
在这里插入图片描述
此时,栈中元素:
在这里插入图片描述
继续,
后续加入以下两个数,
在这里插入图片描述
此时栈中元素:
在这里插入图片描述
此时单独处理这个栈,依次弹出其中每个元素
此时,3 不是因为 任何元素的出现 而弹出的
而是因为遍历完了,不得不弹出

所以,右面比它大的 为空,左面比它大的 为下一个数5
弹出3以后,
在这里插入图片描述
特别注意:此时,5上面已经没有数了,所以其 右面比它大的数,为空!
在这里插入图片描述
弹出5后,
在这里插入图片描述
6中左右均无比它大的值!
在这里插入图片描述
总结:
该元素左边离它最近的比它大的是 该元素出栈后的栈顶元素,如果出栈后栈空,那么该元素左边没有比它大的数
该元素右边离它最近的比它大的数是 使其弹出栈的数
如果整个数组遍历完了,栈中元素单独弹出,但是此时,弹出的所有的数,都没有右边比它大的数!而左边比它大的数,就是其栈中下一个数。
如果一个数既没有因为一个数弹出,在栈中也没有下一个数,那其左右两边,不存在比它大的数。

特殊情况:
数组中的数,相等
在这里插入图片描述

压入栈的时候,下标压在一起:
在这里插入图片描述
此时,6进入后,0,1位置的数,一起结算。

下一个例子:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
此时,5压入。
在这里插入图片描述
3压入:
在这里插入图片描述
此时,6进入,
在这里插入图片描述
0-2 一起弹出,共同结算

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值