单调栈用于在一个序列中,求出每一个数在其左边(右边)第一个比它小(大)的数,由于我们能发现对于每个元素最多进栈一次,最多出栈一次,那么最多是2n。所以时间复杂度是o(n)
左边小版本:
#include <iostream>
using namespace std;
const int N=100010;
int stk[N],tt=-1;
int n;
int main()
{
cin>>n;
for(int i=0;i<n;i++)
{
int x;
cin>>x;
while(tt!=-1&&stk[tt]>=x)tt--;
if(tt!=-1) cout<<stk[tt]<<' ';
else cout<<-1<<' ';
stk[++tt]=x;
}
return 0;
}
左边大版本:
#include <iostream>
using namespace std;
const int N=100010;
int n;
int stk[N],tt=-1;
int main()
{
cin>>n;
for(int i=0;i<n;i++)
{
int x;
cin>>x;
while(tt!=-1&&stk[tt]<=x) tt--;
if(tt!=-1) cout<<stk[tt]<<' ';
else cout<<-1<<' '
stk[++tt]=x;
}
return 0;
}
如果要算右边的大/小版本,只需要先开个数组先将数据存进去,然后用for倒序循环数组,逻辑与左边一致。
右边小版本:
#include <iostream>
using namespace std;
const int N=100010;
int n;
int stk[N],tt=-1;
int a[N];
int main()
{
cin>>n;
for(int i=0;i<n;i++) cin>>a[i];
for(int i=n-1;i>=0;i--)
{
while(tt!=-1&&stk[tt]>=a[i])tt--
if(tt!=-1) cout<<stk[tt]<<' ';
else cout<<-1<<' ';
skt[++tt]=a[i];
}
return 0;
}
右边大版本:
#include <iostream>
using namespace std;
const int N=100010;
int n;
int stk[N],tt=-1;
int a[N];
int main()
{
cin>>n;
for(int i=0;i<n;i++) cin>>a[i];
for(int i=n-1;i>=0;i--)
{
while(tt!=-1&&stk[tt]<=a[i])tt--
if(tt!=-1) cout<<stk[tt]<<' ';
else cout<<-1<<' ';
skt[++tt]=a[i];
}
return 0;
}