C++ 单调栈原理与模板

单调栈就是具有单调性的栈,他依旧是一个栈结构,只不过里面的数据是递增或递减的(严格的增或减)

模板如下:

#include <iostream>

#include <stack>

using namespace std;

const int N = 3e6 + 10;

int a[N];

int n;

void test1()

{

stack<int> st;// 维护一个单调递增的栈

for(int i = 1; i <= n; i++)

{

//栈里面大于等于a[i] 的元素全部出栈

while(st.size() && st.top() >= a[i]) st.pop();

st.push(a[i]);

}

}

void text2()

{

stack<int> st; // 维护一个单调递减的栈

for(int i = 1; j<= n; i++)

{

//栈里面小于等于a[i] 的元素全部出栈

while(st.size() && st.top() <= a[i]) st.pop();

st.push(a[i]);

}

}

int main()

{

text1();

text2();

return 0;

}

单调栈解决的问问题

寻找当前元素左侧,理它最近,并且比他大的元素在哪;

寻找当前元素左侧,理它最近,并且比他小的元素在哪;

寻找当前元素右侧,理它最近,并且比他大的元素在哪;

寻找当前元素右侧,理它最近,并且比他大的元素在哪;

寻找当前元素左侧,理它最近,并且比他大的元素在哪;

寻找当前元素左侧,理它最近,并且比他大的元素在哪;

从左往右遍历元素,构造一个单调递减的栈,插入当前我位置的元素

如果栈为空,则左侧不存在比当前元素大的元素;

如果栈为非空,则插入当前位置时的栈顶元素就是所要找的元素;

注意:因为我们要找的是最终结果,因此,栈里面存在每个元素的下标

代码的实现:

单调递减的栈 左边

const int n = 1e5 + 10;

int n;

int a[N];

int ret[N];

void test()

{

stack<int> st; // 单调递减的栈

for(int i = 1; i <= n; i++)

{

while(st.size() && a[st.top()] <= a[i]) st.pop();

if(st.size()) ret[i] = st.top(); //下标

st.push(i);

}

for(int i = 1; i <= n; i++)

cout << ret[i] << " ";

cout << endl;

}

int mian()

{

cin >> n;

for(int i = 1; i <= n; i++)

{

cin >> a[i];

}

test();

return 0;

}

单调递增的栈 左边

#include <iostream>

#include <stack>

using namespace std;

const int n = 1e5 + 10;

int n;

int a[N];

int ret[N];

void test()

{

stack<int> st; // 单调递增的栈

for(int i = 1; i <= n; i++)

{

while(st.size() && a[st.top()] >= a[i]) st.pop();

if(st.size()) ret[i] = st.top(); //下标

st.push(i);

}

for(int i = 1; i <= n; i++)

cout << ret[i] << " ";

cout << endl;

}

int mian()

{

cin >> n;

for(int i = 1; i <= n; i++)

{

cin >> a[i];

}

test();

return 0;

}

右边 单调递减的栈

const int n = 1e5 + 10;

int n;

int a[N];

int ret[N];

void test()

{

stack<int> st; // 单调递减的栈

for(int i = 1; i <= n; i++)

{

while(st.size() && a[st.top()] <= a[i]) st.pop();

if(st.size()) ret[i] = st.top(); //下标

st.push(i);

}

for(int i = n; i >= 1; i--)

cout << ret[i] << " ";

cout << endl;

}

int mian()

{

cin >> n;

for(int i = 1; i <= n; i++)

{

cin >> a[i];

}

test();

return 0;

}

右边 单调增的栈

const int n = 1e5 + 10;

int n;

int a[N];

int ret[N];

void test()

{

stack<int> st; // 单调递增的栈

for(int i = 1; i <= n; i++)

{

while(st.size() && a[st.top()] >= a[i]) st.pop();

if(st.size()) ret[i] = st.top(); //下标

st.push(i);

}

for(int i = 1; i <= n; i++)

cout << ret[i] << " ";

cout << endl;

}

int mian()

{

cin >> n;

for(int i = n; i >= 1; i--)

{

cin >> a[i];

}

test();

return 0;

}

相关推荐
2201_756206342 小时前
STM32F407 + ML307 阿里云物联网项目总结
c语言·开发语言·嵌入式硬件
东北甜妹2 小时前
Python脚本
java·开发语言·前端
常利兵2 小时前
Android 集合探秘:ArrayMap 与 SparseArray 的奇妙之旅
android·算法·哈希算法
滴滴答滴答答2 小时前
LeetCode Hot100 之 41 缺失的第一个正数
算法·leetcode·职场和发展
rgb2gray2 小时前
论文详解:基于POI与出租车轨迹的城市多中心结构静态-动态多重分形特征
人工智能·python·算法·机器学习·数据分析·可解释
Zarek枫煜2 小时前
[特殊字符]栈(Stack)原理详解 \+ Zig / C3 双语言实现
c语言·单片机·嵌入式硬件·算法
NGC_66112 小时前
ConcurrentHashMap1.8 多线程扩容机制
java·开发语言
jz_ddk2 小时前
[实战] CIC滤波器设计与实现
人工智能·算法·机器学习·数字信号处理·cic滤波器
Sakinol#2 小时前
Leetcode Hot 100 ——多维动态规划
算法·leetcode·动态规划