题目描述
给一个长度为 N 的数组,一个长为 K 的滑动窗体从最左端移至最右端,你只能看到窗口中的 K 个数,每次窗体向右移动一位,如下图:
|窗口位置|最小值|最大值|
|:-:|:-:|:-:|
|[1 3 -1] -3 5 3 6 7[1 3 -1] -3 5 3 6 7|−1−1|33|
| 1 [3 -1 -3] 5 3 6 7 1 [3 -1 -3] 5 3 6 7|−3−3|33|
| 1 3 [-1 -3 5] 3 6 7 1 3 [-1 -3 5] 3 6 7|−3−3|55|
| 1 3 -1 [-3 5 3] 6 7 1 3 -1 [-3 5 3] 6 7|−3−3|55|
| 1 3 -1 -3 [5 3 6] 7 1 3 -1 -3 [5 3 6] 7|33|66|
| 1 3 -1 -3 5 [3 6 7] 1 3 -1 -3 5 [3 6 7]|33|77|
你的任务是找出窗体在各个位置时的最大值和最小值。
输入格式:
第 1 行:两个整数 N 和 K;
第 2 行:N 个整数,表示数组的 N 个元素(≤2×109≤2×109);
输出格式:
第一行为滑动窗口从左向右移动到每个位置时的最小值,每个数之间用一个空格分开;
第二行为滑动窗口从左向右移动到每个位置时的最大值,每个数之间用一个空格分开。
样例
Inputcopy | Outputcopy |
---|---|
8 3 1 3 -1 -3 5 3 6 7 | -1 -3 -3 -3 3 3 3 3 5 5 6 7 |
思路:
这道题是通过遍历数组,用两个队列分别记录最大值和最小值,根据窗口改变队列中的最大值和最小值。
代码:
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <deque>
using namespace std;
typedef long long ll;
typedef double db;
int n,m;
int a[1000005];
int b[1000005];
int c[1000005];
deque<int> qx,qn;
int cnt;
int main(){
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
for(int i=0;i<n;i++){
while(!qx.empty()&&a[i]>=a[qx.back()])
qx.pop_back();
qx.push_back(i);
while(!qn.empty()&&a[i]<=a[qn.back()])
qn.pop_back();
qn.push_back(i);
if(i>=m-1){
while(!qx.empty()&&qx.front()<=i-m) qx.pop_front();
b[cnt]=a[qx.front()];
while(!qn.empty()&&qn.front()<=i-m) qn.pop_front();
c[cnt++]=a[qn.front()];
}
}
for(int i=0;i<cnt;i++){
cout<<c[i]<<' ';
}
cout<<endl;
for(int i=0;i<cnt;i++){
cout<<b[i]<<' ';
}
return 0;
}