C++中单调栈的基本性质介绍

 更新时间:2021年07月12日 17:33:05   作者:Adherer  
这篇文章主要介绍了单调栈的基本性质介绍,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下

单调栈的定义:

单调栈就是栈内元素单调递增或者单调递减的栈,单调栈只能在栈顶操作。

为了更好的理解单调栈,则可将单调栈用生活情形模拟实现,例如:

我们借用拿号排队的场景来说明下。现在有很多人在排队买可乐,每个人手里都拿着号,越靠前的人手里的号越小,

但是号不一定是连续的。小明拿了号后并没有去排队,而是跑去约会了。等他回来后,发现队伍已经排得很长了,

他不能直接插入到队伍里,不然人家以为他是来插队的。小明只能跑到队伍最后,挨个询问排队人手里的号,

小明认为号比他大的人都是“插队”的,于是小明就会施魔法把这些人变消失,直到小明找到号比他小的为止。

在上面这个场景里,大家排的队伍就像是单调栈,因为大家手里拿的号是单调递增的。

而小明找自己位置的这个过程就是元素加入单调栈的过程。新加入的元素如果加到栈顶后,

如果栈里的元素不再是单调递增了,那么我们就删除加入前的栈顶元素,

就像小明施魔法把“插队”的人变消失一样。直到新元素加入后,栈依然是单调递增时,我们才把元素加进栈里。

(这样做的目的是“维护”单调栈,是单调栈保持原来的单调性不变)

从数组的角度阐述单调栈的性质:

给定一个包含若干个整数的数组,我们从第 1 个元素开始依次加入单调栈里,并且加入后更新单调栈。

那么单调栈有这样的性质:对于单调递增的栈,如果此时栈顶元素为 b,加入新元素 a 后进行更新时,

如果 a 大于 b,说明 a 在数组里不能再往左扩展了(由于单调栈的单调递增性质,b前面的元素均小于a),

也就是说,如果从 a 在数组中的位置开始往左边遍历,则 a 一定是第一个比 b 大的元素;

如果 a 小于 b,说明在数组里,a 前面至少有一个元素不能扩展到 a 的位置(至少有b元素,因为b的值要大于a,如果此时再加入新的

a,那么单调栈便不再单调,所以元素a此时不能压入栈顶,因为这并不是元素a"应该"在的位置,只有当元素a找到自己的位置时

元素a方能压入栈中,而这样做的前提是不改变单调栈的单调性),也就是对于这些元素来说,a 是其在数组右侧第一个比它小的元素。

单调栈的维护是 O(n) 级的时间复杂度,因为所有元素只会进入栈一次,并且出栈后再也不会进栈了。

单调栈的性质:

1.单调栈里的元素具有单调性

2.元素加入栈前,会在栈顶端把破坏栈单调性的元素都删除

3.使用单调栈可以找到元素向左遍历第一个比他小的元素,也可以找到元素向左遍历第一个比他大的元素。

对于第三条性质的解释(最常用的性质):

对于单调栈的第三条性质,你可能会产生疑问,为什么使用单调栈可以找到元素向左遍历第一个比他大的元素,

而不是最后一个比他大的元素呢?我们可以从单调栈中元素的单调性来解释这个问题,由于单调栈中的元素只能是单调递增或者是单调

递减的,所以我们可以分别讨论这两种情况(假设不存在两个相同的元素):

1.当单调栈中的元素是单调递增的时候,根据上面我们从数组的角度阐述单调栈的性质的叙述,可以得出:

(1).当a > b 时,则将元素a插入栈顶,新的栈顶则为a

(2).当a < b 时,则将从当前栈顶位置向前查找(边查找,栈顶元素边出栈),直到找到第一个比a小的数,停止查找,将元素a

插入栈顶(在当前找到的数之后,即此时元素a找到了自己的“位置”)

2.当单调栈中的元素是单调递减的时候,则有:

(1).当a < b 时,则将元素a插入栈顶,新的栈顶则为a

(2).当a > b 时,则将从当前栈顶位置向前查找(边查找,栈顶元素边出栈),直到找到第一个比a大的数,停止查找,将元素a

插入栈顶(在当前找到的数之后,即此时元素a找到了自己的“位置”)

到此这篇关于单调栈的基本性质介绍的文章就介绍到这了,更多相关单调栈的基本性质内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++一个函数如何调用其他.cpp文件中的函数

    C++一个函数如何调用其他.cpp文件中的函数

    这篇文章主要介绍了C++一个函数如何调用其他.cpp文件中的函数问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • 搭建C语言开发环境(Windows平台)汇总

    搭建C语言开发环境(Windows平台)汇总

    本文给大家汇总了5种在WIN平台下搭建C语言开发环境的方法,包括一、在Windows平台配置GNU环境,二、使用Sublime Test开发C语言程序,三、使用VisualStudio开发C语言程序,四、搭建EclipseCDT集成开发环境,五、搭建Clion集成开发环境,有需要的小伙伴可以参考下
    2015-11-11
  • C++ static函数调用问题小结

    C++ static函数调用问题小结

    静态成员变量是在程序编译时分配空间,而在程序结束时释放空间,这篇文章主要介绍了C++ static函数调用问题小结,需要的朋友可以参考下
    2024-03-03
  • C/C++ extern关键字用法示例全面解析

    C/C++ extern关键字用法示例全面解析

    这篇文章主要为大家介绍了C/C++ extern关键字用法示例全面解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-01-01
  • 十进制与BCD码转换的算法详解

    十进制与BCD码转换的算法详解

    BCD转换成十进制 BCD码是指用二进制来表示十进制数的编码,即用4位二进制来表示一位十进制数,因此4位二进制数表示最大的十进制数9(1001),只取十六个数中的十个数(有别于8421码)
    2021-09-09
  • 基于Matlab实现多目标粘液霉菌算法的示例代码

    基于Matlab实现多目标粘液霉菌算法的示例代码

    多目标粘液霉菌算法(MOSMA),这是最近开发的粘液霉菌算法(SMA)的多目标变体,用于处理工业中的多目标优化问题。本文将用Matlab实现这一算法,需要的可以参考一下
    2022-05-05
  • 使用C++实现迷宫游戏

    使用C++实现迷宫游戏

    这篇文章主要为大家详细介绍了C++实现迷宫游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-03-03
  • C++实现将图片转换为马赛克效果的示例代码

    C++实现将图片转换为马赛克效果的示例代码

    这篇文章主要为大家详细介绍了C++如何实现将图片转换为马赛克效果,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以了解一下
    2023-01-01
  • VSCode中C/C++编码乱码问题的两种解决方法

    VSCode中C/C++编码乱码问题的两种解决方法

    在中国地区,Windows 系统中的 cmd 和 PowerShell 默认编码是 GBK,但 VSCode 默认使用 UTF-8 编码,这种编码不一致会导致在 VSCode 终端中运行 C/C++ 程序时出现乱码,以下介绍两种方法来解决这一问题,需要的朋友可以参考下
    2025-03-03
  • 深度解析C语言中数据的存储

    深度解析C语言中数据的存储

    本文详细介绍了C语言中数据的存储,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-05-05

最新评论