C++ 高级数据结构————[ 单调栈 ]

每周一篇的算法文章来了

今天讲解的是高级数据结构中的——单调栈

单调栈,顾名思义,就是升级版的栈()

先回顾一下栈把

,是一种线性表,它的特点是只能从一边进出,并且先进后出,后进先出。就想枪的弹夹一样。

而单调栈,跟他有一点不同

单调栈,每时每刻都要保持栈中呈现单调递增或单调递减 

但是,有一个问题:

还是举个栗子

如果把6,7,12,3,1,8依次入栈,那么就会呈现这种样子

C++ 高级数据结构————[ 单调栈 ]_第1张图片 

 怎么看,他都不是单调递增或递减

那我们就要引入单调栈的方法了

一.单调递增栈

单调递增栈中的单调递增,指的是依次出栈的数据呈单调递增

就比如C++ 高级数据结构————[ 单调栈 ]_第2张图片

 

在出栈时,顺序为1,2,3,4,5,6

回到刚才的栗子

C++ 高级数据结构————[ 单调栈 ]_第3张图片

如果要达到单调递增栈

顺序就是这样的:

首先,6入栈

C++ 高级数据结构————[ 单调栈 ]_第4张图片

 接着,7如果入栈,就不满足单调递增,所以要把6踢了,让7入栈

C++ 高级数据结构————[ 单调栈 ]_第5张图片

 然后12要入栈,把7踢了,保证单调性

C++ 高级数据结构————[ 单调栈 ]_第6张图片

 接着,3正常入栈,能够保持单调递增

C++ 高级数据结构————[ 单调栈 ]_第7张图片

 1也正常入栈

C++ 高级数据结构————[ 单调栈 ]_第8张图片

因为8要入栈,所以为了保持单调性,必须把1和3踢了

C++ 高级数据结构————[ 单调栈 ]_第9张图片 

 最后的单调递增栈的样子

代码:

单调递增栈:找到右起第一个比当前数字大的元素

for (int i=T.size()-1;i>=0;i--){
    while(!st.empty()&&T[st.top()]<=T[i]){
        st.pop();
    }
    st.push(i);
}

二.单调递减栈

与单调递增栈相反,单调递减栈是按照出栈顺序来说从大到小

还是模拟一遍栗子:

首先6照常进栈

C++ 高级数据结构————[ 单调栈 ]_第10张图片

 7也是照常进栈,并且能保持单调递减性

C++ 高级数据结构————[ 单调栈 ]_第11张图片

 12也照常进栈

C++ 高级数据结构————[ 单调栈 ]_第12张图片

这时,3要进栈,为了保持单调性,必须把比他大的都踢出去,也就是所有

C++ 高级数据结构————[ 单调栈 ]_第13张图片 

 因为1要进栈,并且保持单调性,所以踢了3

C++ 高级数据结构————[ 单调栈 ]_第14张图片

最后8照常进栈

C++ 高级数据结构————[ 单调栈 ]_第15张图片 

 

整个的单调递减栈就是这样的

代码:

找出左起第一个小于等于当前数字的元素

for (int i=0;iT[i]){
        st.pop();
    }
    st.push(i);
}

作用:

单调栈可以以O(n)的时间复杂度求出某个数的左边第一个比他小于的或右边第一个比他大于的

例题:

题目描述

给出项数为n的整数数列a1…n。定义函数 f(i) 代表数列中第 i个元素之后第一个大于 ai 的元素的下标,即 f(i)=miniai{j}。若不存在,则f(i)=0,试求出 f(1…n) 

输入

第一行一个正整数n,第二行n个正整数 a1…n。

输出

一行n个整数f(1…n)的值。

 

样例输入1
5
1 4 2 3 5
样例输出1
2 5 4 5 0

单调递增栈的模板题

# include 
# include 
# include 
# include 
using namespace std;
# define int long long
int n,a[3000005],f[3000005];
stack  s;
signed main(){
	scanf("%lld",&n);
	for (int i=1;i<=n;i++){
		scanf("%lld",&a[i]);
	}
	for (int i=n;i>=1;i--){
		while(!s.empty()&&a[s.top()]<=a[i]){
			s.pop();
		}
		f[i]=s.empty()?0:s.top();
		s.push(i);
	}
	for (int i=1;i<=n;i++){
		printf("%lld ",f[i]);
	}
	return 0;
}

---------------------------------------------------------------------------------------------------------------------------------

今天对单调栈的讲解就到这里

有什么问题大家可以随时评论区讨论

C++ 高级数据结构————[ 单调栈 ]_第16张图片

 

你可能感兴趣的:(c++,算法详解,数据结构,数据结构,c++,算法,开发语言,单调栈)