Sliding Window
题意:
给出一个数组,有一个滑窗每次可以包括k个数(从最左端开始),每次向右移动一步,求每次滑窗中k个数中的最大值和最小值。
分析:
用一个单调递增队列求最小值,一个单调递减队列求最大值,但是因为滑窗的大小为k,所以每次要对队列中最左端的位置进行判断。
代码:

#include <stack> #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> using namespace std; #define ll long long #define ull unsigned long long #define cls(x) memset(x,0,sizeof(x)) #define clslow(x) memset(x,-1,sizeof(x)) const int maxn=1e6+100; int n,k; int a[maxn]; int que[maxn],minval[maxn],maxval[maxn]; void getMin() { int head=0,rear=0; for(int i=1;i<=n;i++){ while(rear>head&&a[que[rear-1]]>=a[i]) rear--; que[rear++]=i; if(i<k) continue; while(que[head]<i-k+1) head++; minval[i]=a[que[head]]; } } void getMax() { int head=0,rear=0; for(int i=1;i<=n;i++){ while(rear>head&&a[que[rear-1]]<=a[i]) rear--; que[rear++]=i; if(i<k) continue; while(que[head]<i-k+1) head++; maxval[i]=a[que[head]]; } } void print() { for(int i=k;i<=n;i++){ if(i>k) printf(" "); printf("%d",minval[i]); } printf(" "); for(int i=k;i<=n;i++){ if(i>k) printf(" "); printf("%d",maxval[i]); } printf(" "); } int main() { // freopen("in.txt","r",stdin); while(scanf("%d%d",&n,&k)!=EOF) { for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } getMin(); getMax(); print(); } return 0; }