AcWing 154. 滑动窗口

AcWing 154 滑动窗口

一、题目描述

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

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

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

以下是一个例子:

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

窗口位置 最小值 最大值
[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、维护一个队列,来一个新人,将队列中大于它的老家伙们干死,保留比它小的老家伙们。

2、道理:
(1)老家伙比新人还大,新人又小活的时间又长,老家伙永远也不可能为后面提供帮助了,所以干死~
tt--
(2)不管是不是更小,只要寿命到了,也一样要死。
hh++

3、其实,这本身是一个双端队列,不是传统的队列,出队的可能是队头,也可能是队尾。

求窗口中的最大值正好与之相反,小修改一下即可。

三、C++代码

#include <bits/stdc++.h>

using namespace std;
const int N = 1000010;
int n;
int k;
int a[N];
int q[N], hh, tt;
int main() {
    cin >> n >> k;
    for (int i = 1; i <= n; i++) cin >> a[i];

    // 初始化队列
    hh = 0, tt = -1;
    for (int i = 1; i <= n; i++) {
        // Q1:队列里面放的是什么?
        // A1:是数组下标,是编号,不是值,需要值时,可以通过a[q[hh]]去取值

        // Q2:队列的存入形态是什么样的?
        // A2: hh....tt,hh在左,tt在右

        // Q3:什么样的需要出队列?
        // A3: (1)距离当前位置超过窗口范围
        //      (2) 在窗口范围内,但对后续没有可能发挥作用:区间内的人员,有比你更年轻、更漂亮的,怎么选美也选不到你
        while (hh <= tt && i + 1 - k > q[hh]) hh++; // q[hh]:窗口的左起点,hh++:减小窗口长度
        while (hh <= tt && a[q[tt]] >= a[i]) tt--;  // tt--:减小窗口长度
        // q[],hh,tt 三者组成了一个模拟的队列数据结构,对外提供:查询队列中最小值位置的服务q[hh],对内三者互相协作
        //  换言之:q[hh]是对外的,hh,tt是数据结构内部概念,不能混淆
        q[++tt] = i;
        // 只有在区间长度够长的情况下,才能输出区间最小值
        if (i >= k) printf("%d ", a[q[hh]]);
    }

    puts("");

    hh = 0, tt = -1;
    for (int i = 1; i <= n; i++) {
        while (hh <= tt && i + 1 - k > q[hh]) hh++;
        while (hh <= tt && a[q[tt]] <= a[i]) tt--;
        q[++tt] = i;
        if (i >= k) printf("%d ", a[q[hh]]);
    }
    return 0;
}
posted @   糖豆爸爸  阅读(802)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
历史上的今天:
2019-09-10 明智的攻击
Live2D
点击右上角即可分享
微信分享提示