滑动窗口

题目

给定一个大小为n≤106的数组。

有一个大小为k的滑动窗口,它从数组的最左边移动到最右边。

您只能在窗口中看到k个数字。

每次滑动窗口向右移动一个位置。

以下是一个例子:

该数组为[1 3 -1 -3 5 3 6 7],k为3。

滑动窗口_第1张图片
输出格式
输出包含两个。

第一行输出,从左至右,每个位置滑动窗口中的最小值。

第二行输出,从左
至右,每个位置滑动窗口中的最大值。

输入样例

8 3
1 3 -1 -3 5 3 6 7

输出样例

-1 -3 -3 -3 3 3
3 3 5 5 6 7

C++

//数组模拟单调队列

#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e6+10;
int a[N],q[N];
int n,k;
int main()
{
    scanf("%d%d", &n,&k);
    for(int i=0;i<n;i++)
    scanf("%d",&a[i]);
    int t=-1,h=0;
    for(int i= 0;i<n;i++)
    {
        if(h<=t&&i-k+1>q[h]) h++;//当队列长度大于k时 弹出队首
        while(h<=t&&a[q[t]]>=a[i]) t--;  //让队首的值最小
        q[++t] = i;
        if(i>=k-1) printf("%d ",a[q[h]]);
    }
    printf("\n");
    t=-1,h=0;
    for(int i=0;i<n;i++)
    {
        if(h<=t&&i-k+1>q[h]) h++;  //当队列长度大于k时 弹出队首
        while(h<=t&&a[q[t]]<=a[i]) t--;  
        q[++t] = i;
        if(i>=k-1) printf("%d ",a[q[h]]);
    }
    return 0;
}

暴力超时了。。。

#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e6+10;
int a[N],q[N];
int n,k;
int main()
{
    scanf("%d%d", &n,&k);
    for(int i=0;i<n;i++)
    scanf("%d",&a[i]);
    for(int i=k-1;i<n;i++)
    {
        int min=a[i+1-k];
        for(int j=i+1-k;j<=i;j++)
        {
            if(min>a[j])
            min=a[j];
        }
        printf("%d ", min);
    }
    puts("");
    for(int i=k-1;i<n;i++)
    {
        int max=a[i+1-k];
        for(int j=i+1-k;j<=i;j++)
        {
            if(max<a[j])
            max=a[j];
        }
        printf("%d ", max);
    }
    return 0;
}

你可能感兴趣的:(基础算法)