//单调队列求滑动窗口的最大值和最小值
//题意是给一个n个数,在每k个数区间内
//求最大值和最小值
//单调队列:队列中的元素是单调的。
//求最小值的时候:进队的时候将队尾部大于当前要进的元素全部出队
//这样,队列的头部就是最小值
//反之,求最大值也是一样
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn = 1e6 + 8;
int a[maxn];
int n,k;
int vmi[maxn];
int vmx[maxn];
int deq[maxn];
void input(){
for (int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
}
void getmin(){
int head=0,tail=0;
int cnt = 0;
for (int i=1;i<=n;i++){
while(tail > head && a[deq[tail-1]]>=a[i])
tail--;
deq[tail++] = i;
if (i-k+1>=0){
vmi[i-k+1] = a[deq[head]];
if (i - k + 1 == deq[head]) // 这里的意思是最小值是第x个区间的最左边的值,这个值不在求的
//下一个区间内
head++;
}
}
}
void getmax(){
int head = 0,tail = 0;
int cnt = 0;
for (int i=1;i<=n;i++){
while (tail > head && a[deq[tail-1]] <= a[i])
tail--;
deq[tail++] = i;
if (i-k+1>=0){
vmx[i-k+1] = a[deq[head]];
if (i-k+1 == deq[head]){ // 这里的意思是最小值是第x个区间的最左边的值,这个值不在求的
//下一个区间内
head ++ ;
}
}
}
}
void print(int a[]){
for (int i=1;i<=n-k+1;i++){
printf("%d%c",a[i],(i==n-k+1)?'\n':' ');
}
}
void solve(){
getmax();
getmin();
print(vmi);
print(vmx);
}
int main(){
//freopen("1.txt","r",stdin);
while(scanf("%d %d",&n,&k)!=EOF){
input();
solve();
}
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/timelimite/article/details/47011075