slideing window题解

来源:互联网 发布:linux服务总结 编辑:程序博客网 时间:2024/05/19 18:11

这题对时间复杂度要求很高,一般的解法过不了,要用双向队列

双向队列是两段均可删除和插入的队列

#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想等时,要将其删去;

0 0
原创粉丝点击