专题学习1 - I - 滑动窗口

题意

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

窗口位置 最小值 最大值
[1 3 -1] -3 5 3 6 7 −1 3
1 [3 -1 -3] 5 3 6 7 −3 3
1 3 [-1 -3 5] 3 6 7 -3 5
1 3 -1 [-3 5 3] 6 7 -3 5
1 3 -1 -3 [5 3 6] 7 3 6
1 3 -1 -3 5 [3 6 7] 3 7

你的任务是找出窗体在各个位置时的最大值和最小值。

输入格式

第 1 行:两个整数 NK
第 2 行:N 个整数,表示数组的 N 个元素(≤2×10^9);

输出格式

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

思路

单项队列模板题。

代码

#include <iostream>
using namespace std;
const int N = 5 + 1e6;

int a[N];
int q1[N], q2[N];

int main() {
    int n, m, hh, tt;
    cin >> n >> m;
    for (int i = 1; i <= n; i++) scanf("%d", &a[i]);

    //min_deque
    hh = 1, tt = 0;
    for (int i = 1; i <= n; i++) {
        while (hh <= tt && q1[hh] + m <= i) hh++;
        while (hh <= tt && a[i] < a[q1[tt]]) tt--;
        q1[++tt] = i;
        if (i >= m) printf("%d ", a[q1[hh]]);
    }
    cout << '\n';

    //max_deque
    hh = 1, tt = 0;
    for (int i = 1; i <= n; i++) {
        while (hh <= tt && q2[hh] + m <= i) hh++;
        while (hh <= tt && a[i] > a[q2[tt]]) tt--;
        q2[++tt] = i;
        if (i >= m) printf("%d ", a[q2[hh]]);
    }
    cout << '\n';

    return 0;
}
posted @   haifan16  阅读(50)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示