一、单调栈的定义与分类
单调栈中存放的数据应该是有序的,单调栈分为单调递增栈和单调递减栈
- 单调递增栈:从栈底到栈顶的数据为从大到小(利用:如果栈顶元素大于要入栈的元素,将其弹出,将新元素入栈)
- 单调递减栈:从栈底到栈顶的数据为从大到小(利用:如果栈顶元素小于要入栈的元素,将其弹出,将新元素入栈)
什么时候使用单调栈
- 给定一个序列,求序列中的每一个数左边(右边)第一个比它小的(大的)数或其在什么地方
二、单调递增栈
求左边第一个比它小的数
for(int i=1;i<=n;i++)
{
int x;
scanf("%d",&x);
while(t!=0&&stk[t]>=x)
{t--;}
if(t==0)
{printf("-1 ");}
else
{printf("%d ",stk[t]);}
stk[++t]=x;
}
求左边第一个比它小的数的位置
for(int i=1;i<=n;i++)
{
while(S.size()&&a[S.top()]>=a[i])
{S.pop();}
if(S.empty())
{l[i]=0;}
else
{l[i]=S.top();S.push(i);}
}
for(int i=1;i<=n;i++)
{
while(t!=0&&a[stk[t]]>=a[i])
{t--;}
if(t==0)
{l[i]=0;}
else
{l[i]=stk[t];}
stk[++t]=i;
}
三、单调递减栈
求序列中每一个数左边第一个比它小的数
for(int i=1;i<=n;i++)
{
int x;
scanf("%d",&x);
while(t!=0&&stk[t]<=x)
{t--;}
if(t==0)
{printf("-1 ");}
else
{printf("%d ",stk[t]);}
stk[++t]=x;
}
单调递减栈求左边第一个比它大的数的位置
for(int i=n;i>=0;i--)
{
while(t!=0&&a[stk[t]]<=a[i])
{t--;}
if(t==0)
{l[i]=0;}
else
{l[i]=stk[t];}
stk[++t]=i;
}
单调栈还学得有点浅,还要多学学