这题对时间复杂度要求很高,一般的解法过不了,要用双向队列
双向队列是两段均可删除和插入的队列
#include<stdio.h>
#include<deque>
#include<algorithm>
using namespace std;
int Min[1000000],Max[1000000],num[1000000];
int i,j,n,k,sum;
deque<int>c;
int shu;
void findmin()
{
sum=0;
for(i=0;i<n;i++){
if(!c.empty()&&c.front()==i-k)
c.pop_front();
while(!c.empty()){
if(num[c.back()]>num[i]){
c.pop_back();
}
else break;
}
c.push_back(i);
if(i>=k-1){
Min[sum]=num[c.front()];
sum++;
}
}
shu=sum;
}
void findmax()
{
int sum=0;
for(i=0;i<n;i++){
if(i>=k&&c.front()==i-k)
c.pop_front();
while(!c.empty()){
if(num[c.back()]<num[i]){
c.pop_back();
}
else break;
}
c.push_back(i);
if(i>=k-1){
Max[sum]=num[c.front()];
sum++;
}
}
}
int main()
{
scanf("%d %d",&n,&k);
for(i=0;i<n;i++)
scanf("%d",&num[i]);
findmin();
while(!c.empty()){
c.pop_back();
}
findmax();
int N=0;
for(i=0;i<2;i++){
if(i==1){
N=0;
for(j=0;j<shu;j++){
if(N==1)
printf(" ");
printf("%d",Max[j]);
N=1;
}
printf("\n");
}
else {
N=0;
for(j=0;j<sum;j++){
if(N==1)
printf(" ");
printf("%d",Min[j]);
N=1;
}
printf("\n");
}
}
return 0;
}
思路:
最大值,最小值分开求,思路一样;
列如求最大值时:当队列不为空时,将要进入队列的数,要和队尾元素进行比较,如果队尾元素小就pop掉,直到队列为空或者遇到比它大的队尾值,然后将其入队,当i>=k-1时
要将最大值存下来;当队列不为空且队尾值与i-k想等时,要将其删去;