单调栈与单调队列:相邻元素与滑动窗口

发布于 2026-02-05 16:22 228 字 2 min read

hainoir avatar

hainoir

记录前端实践、算法推演和那些值得反复理解的问题。

  1. 至今

    超星

    前端研发工程师

  2. 至

    好未来

    硬件运维工程师

首页 周刊 时间线 关于 歌单
用 C++ 模板对照单调栈与单调队列:前者寻找左侧较小元素,后者维护滑动窗口最大值与最小值,重点记录元素入队前和窗口移动时的淘汰条件。

单调栈:寻找左侧较小元素

https://www.starrycoding.com/problem/60
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 2e5+9;
ll a[N],l[N];

int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	ll n;cin >> n;
	for(int i = 1;i <= n;++i) cin >> a[i];
	
	stack<int> stk;
	
	for(int i = 1;i <= n;++i)
	{
		while(stk.size() && stk.top() >= a[i]) stk.pop();
		if(stk.empty()) l[i] = -1;  
		else l[i] = stk.top();
		stk.push(a[i]);
	}
	
	for(int i = 1;i <= n;++i) cout << l[i] << ' ';
}

单调队列:滑动窗口最值

//https://www.starrycoding.com/problem/61
#include<bits/stdc++.h>
using namespace std;
using ll = long long ;
const int N = 2e5+9; 
ll a[N];

int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	ll n,k;cin >> n >> k;
	for(int i = 1;i <= n;++i) cin >> a[i];
	
	deque<int> dq;
	//求最大
	for(int i = 1;i <= n;++i)
	{
		//队头合法性
		while(dq.size() && dq.front() <= i-k)dq.pop_front();
		//队尾优越性
		while(dq.size() && a[dq.back()] <= a[i]) dq.pop_back();
		
		dq.push_back(i);
		
		if(i >= k) cout << a[dq.front()] << ' ';
	}
	cout << '\n';
	dq = deque<int>();
	
	for(int i = 1;i <= n;++i)
	{
		//队头合法性
		while(dq.size() && dq.front() <= i-k)dq.pop_front();
		//队尾优越性 
		while(dq.size() && a[dq.back()]>= a[i]) dq.pop_back();
		
		dq.push_back(i);
		
		if(i >= k) cout << a[dq.front()] << ' ';
	}
	
}

本文作者:hainoir · CC BY-NC-SA 4.0

喜欢的话,留下你的评论吧~

评论加载中…

相关文章