单调栈
常见题型:求一个数列左边第一个比它小的数,或右边第一个比它大的数。
暴力做法:外层循环枚举每一个元素x,内层循环找到x左边第一个比它小的数。
for(int i = 0;i < n; i ++ )
{
for(int j = i - 1; j >= 0; j -- )
{
if (a[j] < a[i])
{
cout << a[j];
}
break;
}
}
优化:单调栈
如果两个数满足 x >= y,x < y 这个条件,那么x一定不会作为答案输出,那么我们可以把像x这样的数删掉。删掉后栈内元素就是一个单调的序列了。为维护这个单调性质,在插入x之前,判断栈顶元素,如果>=x,栈顶元素弹出,直到找到第一个 < x 的栈顶元素。
ACwing 830.单调栈
给定一个长度为N的整数数列,输出每个数左边第一个比它小的数,如果不存在则输出-1。
输入格式
第一行包含整数N,表示数列长度。
第二行包含N个整数,表示整数数列。
输出格式
共一行,包含N个整数,其中第i个数表示第i个数的左边第一个比它小的数,如果不存在则输出-1。
数据范围
1≤N≤1051≤N≤105
1≤数列中元素≤1091≤数列中元素≤109
输入样例:
5
3 4 2 7 5
输出样例:
-1 3 -1 2 2
#include <iostream>
using namespace std;
const int N = 100010;
int n;
int stk[N],tt;
int main()
{
cin >> n;
while(n -- )
{
int x;
cin >> x;
while(tt && stk[tt] >= x) tt -- ;
if(tt) cout << stk[tt] << ' ';
else cout << -1 << ' ';
stk[ ++ tt] = x;
}
return 0;
}