题意:用一个窗口来框住几个连续的元素,问每次框住元素的最大值和最小值
这里可以用deque来完美解决这个问题,deque是一种特殊的queue,他在queue的基础上增加了从开头插入,从队尾删除等操作,我们用两个deque分别来维护最大值和最小值,我这里讲一下最大值的做法,最小值一样。
每次向队列里插入元素的时候,都要和队尾元素比较,如果队尾元素小于插入元素,则将队尾元素出队,插入元素和新的队尾继续比较,直至队列已空或者是队尾元素大于或等于插入元素,然后将插入元素插入到队尾,同时因为我们删除了多个元素,所以我们给每一个元素增加一个编号,用来判断这个元素是否在滑动框内,不在的话就将其出队,然后队列的队首元素就是滑动框内的最大值,将这个值记录下来。
A代码
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<string>
#include<deque>
#include<cmath>
using namespace std;
const int N = 1e6 + 30;
struct node {
int val;
int id;
}arr[N];
deque<node> dqmax;
deque<node> dqmin;
int Max[N];
int Min[N];
int main() {
int n, k;
scanf("%d %d", &n, &k);
for (int i = 1; i <= n; i++) {
scanf("%d", &arr[i].val);
arr[i].id = i;
}
for (int i = 1; i <= k; i++) {
if (dqmax.empty()) dqmax.push_back(arr[i]);
else {
while (!dqmax.empty()&&dqmax.back().val < arr[i].val) dqmax.pop_back();
dqmax.push_back(arr[i]);
}
if (dqmin.empty()) dqmin.push_back(arr[i]);
else {
while (!dqmin.empty() && dqmin.back().val > arr[i].val) dqmin.pop_back();
dqmin.push_back(arr[i]);
}
}
Max[1] = dqmax.front().val;
Min[1] = dqmin.front().val;
for (int i = k+1; i <= n; i++) {
while (!dqmax.empty() && dqmax.back().val < arr[i].val) dqmax.pop_back();
dqmax.push_back(arr[i]);
if (dqmax.front().id <= i - k) dqmax.pop_front();
Max[i - k+1] = dqmax.front().val;
while (!dqmin.empty() && dqmin.back().val > arr[i].val) dqmin.pop_back();
dqmin.push_back(arr[i]);
if (dqmin.front().id <= i - k) dqmin.pop_front();
Min[i - k +1] = dqmin.front().val;
}for (int i = 1; i <= n - k + 1; i++) {
printf("%d ", Min[i]);
}
printf("\n");
for (int i = 1; i <= n - k + 1; i++) {
printf("%d ", Max[i]);
}
}
564

被折叠的 条评论
为什么被折叠?



