1.题号:Nc50528

2:题目原文

给一个长度为N的数组,一个长为K的滑动窗体从最左端移至最右端,你只能看到窗口中的K个数,每次窗体向右移动一位,如下图: alt

你的任务是找出窗体在各个位置时的最大值和最小值。 输入描述: 第1行:两个整数N和K; 第2行:N个整数,表示数组的N个元素(≤2×109)

输出描述: 第一行为滑动窗口从左向右移动到每个位置时的最小值,每个数之间用一个空格分开; 第二行为滑动窗口从左向右移动到每个位置时的最大值,每个数之间用一个空格分开。

3 链接:https://ac.nowcoder.com/acm/problem/50528

来源:牛客网

4 基本思路

用数组模拟单调队列,数组q存储下标. 遍历a数组,先判断队列存储的元素个数是否超出k,超出则移除对头,再将最小的值的下标存储到对头,最后输出对头,找最大值同理

5.代码
using namespace std;
const int N = 1e6+9;
int q[N],hh=0,tt=-1;
int n,k;
int a[N];
int main()
{
    cin>>n>>k;
    for(int i=0;i<n;i++)
    {
        cin>>a[i];
    }
    for(int i=0;i<n;i++)
    {
        if(i-q[hh]>=k) hh++;
        while(hh<=tt&&a[q[tt]]>a[i]) tt--;
        q[++tt]=i;
        if(i>=k-1) cout<<a[q[hh]]<<' ';
    }
    puts("");
    hh=0,tt=-1;
    for(int i=0;i<n;i++)
    {
        if(i-q[hh]>=k) hh++;
        while(hh<=tt&&a[q[tt]]<a[i]) tt--;
        q[++tt]=i;
        if(i>=k-1) cout<<a[q[hh]]<<' ';
    }
    return 0;
}