单调栈 & 单调队列

单调栈 & 单调队列

单调栈

引入

单调栈是什么?顾名思义,单调栈即满足单调性的栈结构,与单调队列相比,其只在一端进行进出。

过程

插入

将一个元素插入单调栈时,为维护栈的单调性,需要在保证将该元素插入到栈顶后整个栈满足单调性,并且使弹出的元素最少

伪代码

insert x
while !sta.empty() && sta.top()<x
    sta.pop()
sta.push(x)

单调栈例题

代码实现

#include<bits/stdc++.h>
using namespace std;
int n,a[3000005],b[3000005];
stack <int> s;
int main()
{
	cin >> n;
	for(int i=1;i<=n;i++) cin >> a[i];
	for(int i=n;i>=1;i--)
	{
		while(!s.empty() && a[s.top()] <= a[i]) 
		{
			s.pop();//弹出栈顶比当前数小的
		}
		if(!s.empty())
		{
		    b[i] = s.top();   
		}
		else
		{
		    b[i] = 0;
		}
		s.push(i);
	}
	for(int i = 1;i <= n;i++)
	{
		cout << b[i] << " ";
	}
	return 0;
}

定义也是直接抄OI Wiki

单调队列

引入

首先我们要看一道经典例题,滑动窗口

最暴力的想法很简单,对于每一段 i~i+k-1 的序列,逐个比较来找出最大值(和最小值),时间复杂度约为 O(n * k)。

很显然,这其中进行了大量重复工作,除了开头 k-1 个和结尾 k-1 个数之外,每个数都进行了 k 次比较,而题中 100% 的数据为 n <= 1000000,当 k 稍大的情况下,显然会 TLE。

这时所用到的就是单调队列了。

定义

顾名思义,单调队列的重点分为「单调」和「队列」。

单调 指的是元素的规律递增(或递减)。
队列 指的是元素只能从队头和队尾进行操作。

例题分析

没错,它在这里

代码奉上

//1、维护队首(就是如果你已经是当前的m个之前那你就可以被删了,head++)
//2、在队尾插入(每插入一个就要从队尾开始往前去除冗杂状态)
#include<bits/stdc++.h>
using namespace std;
int n,m;
int q1[1000001],q2[1000001];
int a[1000001];
int min_deque()
{
	int h = 1,t = 0;
	for(int i = 1;i <= n;i++)
	{
		while(h <= t && q1[h] <= i - m) h++;
		while(h <= t && a[i] < a[q1[t]]) t--;
		q1[++t] = i;
		if(i >= m ) cout << a[q1[h]] << " ";
	}  
	cout << "\n";
	return 0;
}
int max_deque()
{
	int h = 1,t = 0;
	for(int i = 1;i <= n;i++)
	{
		while(h <= t && q2[h] <= i - m) h++;
		while(h <=t && a[i] > a[q2[t]]) t--;
		q2[++t] = i;
		if(i >= m) cout << a[q2[h]] << " ";
	}
	return 0;
}
int main()
{
	cin >> n >> m;
	for(int i = 1;i <= n;i++) cin >> a[i];
	min_deque();
	max_deque();
	return 0;
}

完结

posted @ 2024-10-07 21:22  DomiSun  阅读(53)  评论(0)    收藏  举报
/* 点击爆炸效果*/