单调栈

昨天我又做了单调栈的变题,发现懵懵的,今天又重新过了一下发现还好

其实单调栈就是一个单调的栈,里面根据所需要的数字都变成单调的!!这句话很关键啊,就想象已经有了个单调的栈你可以去用

知道到底是个什么样的栈,单调递增还是递减。排除不满足条件的,栈顶的元素其实就是你所需要的(这个话有点抽象)

做了个总结吧

①找出任意一个数字左边靠的最近的比它小的数

这就是个单调递增的栈

然后排除所不需要的,剩下的栈顶就是答案

#include<iostream>
using namespace std;
const int N=100010;
int stk[N],tt;
int main(){
    int n;
    cin>>n;
    while(n--)
    {
        int x;
        cin>>x;
        while(tt&&stk[tt]>=x) tt--;//开始检查如果大于x就出栈,求最靠近的数,出栈的这些数也用不到 
        if(!tt) printf("-1 ");
        else printf("%d ",stk[tt]);//栈顶的数字 
        stk[++tt]=x;//新的数压到栈里面 
    }
    return 0;
}

②找出任意一个数字右边靠的最近的比它大的数

这是个单调递减的栈

但是有一点不一样咯,得先从最右端开始找起

#include<iostream>
using namespace std;
const int N=10010;
int a[N],stk[N],tt,f[N]; 
int main(){
    int n;
    cin>>n;
    for(int i=0;i<n;i++)
        cin>>a[i];
    for(int i=n-1;i>=0;i--)
    {
        while(tt&&stk[tt]<=a[i]) tt--;
        if(!tt)
            f[i]=-1;
        else
            f[i]=stk[tt];
        stk[++tt]=a[i];
    }
    for(int i=0;i<n;i++)
        cout<<f[i]<<" ";
    return 0;
}

③找出任意一个数字右边靠的最近比它大的数的下标

这个用单调栈就有点不一样了,小数据可以直接暴力

大数据我原来还想用结构体存下标....

太麻烦了QAQ

其实不用,刚刚说的栈里其实就是答案,何乐而不为呢

直接让栈离存的数据就是下标不就行了吗

但是存的是下标得注意别忘了hhh

#include<iostream>
using namespace std;
const int N=100010;
int stk[N],tt,a[N],f[N];
int main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    for(int i=n;i>=1;i--)
    {
        while(tt&&a[stk[tt]]<=a[i]) tt--;
        if(!tt)
            f[i]=0;
        else
            f[i]=stk[tt];
        stk[++tt]=i;
    }
    for(int i=1;i<=n;i++)
        cout<<f[i]<<" ";
    return 0; 
}

很漂亮,很巧妙 Orz!!

上一篇:webclient乱码问题


下一篇:牛客数组和字符串2.5