题意:
给定一个长度为n的序列和长度为k的窗口,求每次窗口滑动时窗口内元素的最大值和最小值。
思路:
经典的单调队列题目,这里采用双端队列处理,维护单调非递增(/减)队列
考虑求最小值:
若ar[i]小于等于队尾元素,则不断弹出队尾元素,因为ar[i]比它们有更大的发展空间;
将ar[i]入队,因为当队首元素不断弹出时,其有可能成为最小值;
若队首元素离开窗口则弹出;
输出队首元素。
最大值情况同理。
代码:
#include <iostream> #include <queue> #include <set> #include <map> #include <vector> #include <stack> #include <cmath> #include <algorithm> #include <cstdio> #include <cctype> #include <functional> #include <string> #include <cstring> #include <sstream> #include <deque> using namespace std; typedef long long ll; typedef pair<int,int> P; typedef pair<int,P> Q; const int inf=2e9+9; const int maxn=1e6+9; const int maxx=2e5+9; int n,k,ar[maxn]; deque<int> que; int main() { scanf("%d%d",&n,&k); for(int i=0;i<n;i++) { scanf("%d",&ar[i]); while(!que.empty()&&ar[que.back()]>=ar[i]) que.pop_back(); que.push_back(i); if(i>=k-1) { if(i-que.front()>=k) que.pop_front(); printf("%d ",ar[que.front()]); } } printf("\n"); que.clear(); for(int i=0;i<n;i++) { while(!que.empty()&&ar[que.back()]<=ar[i]) que.pop_back(); que.push_back(i); if(i>=k-1) { if(i-que.front()>=k) que.pop_front(); printf("%d ",ar[que.front()]); } } printf("\n"); }