单调栈和单调队列
用数组模拟出单调栈和单调队列
单调栈常常用来维护离最近的比当前值小或大的值,单调队列维护一个固定区间的最小或最大值;
单调栈维护一个左边比他小的值的代码
1 #include<iostream> 2 using namespace std; 3 int st[100010],n,a[100010]; 4 int tt; 5 int main() 6 { 7 cin>>n; 8 for(int i=1;i<=n;i++) 9 scanf("%d",&a[i]); 10 for(int i=1;i<=n;i++) 11 { 12 while(tt&&st[tt]>=a[i])tt--; 13 if(tt)cout<<a[tt]<<' '; 14 else 15 cout<<"-1 "; 16 st[++tt]=a[i]; 17 } 18 return 0; 19 }
滑动窗口代码:
1 #include<iostream> 2 using namespace std; 3 int n,k; 4 int a[1000010]; 5 int q[1000010];//存下标 6 int main() 7 { 8 9 //scanf("%d%d",&n,&k); 10 cin>>n>>k; 11 for(int i=1;i<=n;i++)cin>>a[i]; 12 int hh=0,tt=-1;//hh表示队头,t t表示队尾 13 for(int i=1;i<=n;i++) 14 { 15 if(hh<=tt&&i-k+1>q[hh])hh++;//如果队列非空且队头已经划出窗口,则弹出队头; 16 while(hh<=tt&&a[q[tt]]>=a[i])tt--;//如果队尾元素大于新加入的元素则队尾元素弹出,因为不可能成为最小值 17 q[++tt]=i; 18 if(i>=k-1)printf("%d ",a[q[hh]]); 19 } 20 printf("\n"); 21 hh=0,tt=-1; 22 for(int i=1;i<=n;i++) 23 { 24 if(hh<=tt && i-k+1 > q[hh] ) hh++; 25 while(hh<=tt && a[q[tt]]<=a[i]) tt--; 26 27 q[++tt]=i; 28 29 if(i-k+1>0) cout<<a[q[hh]]<<" "; 30 31 } 32 //printf("\n"); 33 return 0; 34 }