昨天我又做了单调栈的变题,发现懵懵的,今天又重新过了一下发现还好
其实单调栈就是一个单调的栈,里面根据所需要的数字都变成单调的!!这句话很关键啊,就想象已经有了个单调的栈你可以去用
知道到底是个什么样的栈,单调递增还是递减。排除不满足条件的,栈顶的元素其实就是你所需要的(这个话有点抽象)
做了个总结吧
①找出任意一个数字左边靠的最近的比它小的数
这就是个单调递增的栈
然后排除所不需要的,剩下的栈顶就是答案
#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!!