滑动窗口
活动地址:https://ac.nowcoder.com/discuss/394776?type=101&order=0&pos=6&page=2
思路
单调队列的模板题
其实就一个关键地方:拿窗口中最小值为例,假如现在窗口中是1 3 5 6,再下一次滑动来了一个4,那么很明显窗口中的5 6永远不会是最小值,其实单调队列算是一种暴力的优化,就是新来的值可以排除掉一些永远不会是答案的元素,这样就会使得队列呈单调性,每一个窗口的答案总是在最左边。
代码
#include <iostream> #include <algorithm> #include <string> #include <cstring> #include <map> #include <set> #include <deque> #include <queue> #include <vector> #include <cstring> #include <cstdio> #include <cstdlib> #include <cmath> #define PI acos(-1) using namespace std; typedef long long ll; typedef pair<int,int> pii; const ll maxn = 1e6+10; double eps = 1e-8; int N,K; int arr[maxn]; int q1[maxn],q2[maxn],ff1,ff2,tt1 = -1,tt2 = -1;//模拟队列 int mi[maxn],tail1; int mx[maxn],tail2; int main(){ cin>>N>>K; for(int i = 1;i<=N;i++) scanf("%d",&arr[i]); for(int i = 1;i<=N;i++){ while(ff1 <= tt1 && arr[q1[tt1]] > arr[i]) tt1--; //最小值部分 q1[++tt1] = i; while(q1[ff1]<i-K+1) ff1++; //出队 while(ff2 <= tt2 && arr[q2[tt2]] < arr[i]) tt2--;//最大值部分 q2[++tt2] = i; while(q2[ff2]<i-K+1) ff2++; if(i>=K) mi[tail1++] = arr[q1[ff1]]; if(i>=K) mx[tail2++] = arr[q2[ff2]]; } for(int i = 0;i<tail1;i++) printf("%d ",mi[i]);puts(""); for(int i = 0;i<tail2;i++) printf("%d ",mx[i]); return 0; }