AcWing
  • 首页
  • 课程
  • 题库
  • 更多
    • 竞赛
    • 题解
    • 分享
    • 问答
    • 应用
    • 校园
  • 关闭
    历史记录
    清除记录
    猜你想搜
    AcWing热点
  • App
  • 登录/注册

AcWing 154. 滑动窗口    原题链接    简单

作者: 作者的头像   就是个渣渣 ,  2019-10-19 09:30:48 ,  所有人可见 ,  阅读 788


0


概述

数组长度为n, 滑动窗口大小为k的最小值

题解

1 3 -1 -3 5 5 3 6 7

首先把如果不做优化,n*k

每一步进行观察发现,朴素想法。

其实在每一步的滑动窗口中,保留整个范围内的最小值就可以了,无须其他。
然后队列中队头就是当前窗口的最小值,当窗口向右滑动,滑出时,实际上,最小值会抛出。然后就一个新的最小值补入。

但其实能始终保证队列中的元素是一个单调上升的序列

对于单调,往往有很好的性质,极值就在两边. 查找某个值时用二分即可。

代码

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 1e6 + 10;

int n, k;
int a[N], q[N];

int main() {
    scanf("%d%d", &n, &k);

    for (int i = 0; i < n; i ++) scanf("%d", &a[i]);
    int hh = 0, tt = -1;  // head, tail;  hh > tt 表示当前队列为空

    for (int i = 0; i < n; i ++) {
        // 队列中存储的是坐标 if 只执行一次
        if (hh <= tt && i - k + 1 > q[hh]) hh ++; // 队列不为空且队首元素出了窗口,则队首加一,i为终点坐标,i-k+1为起点坐标

        while (hh <= tt && a[q[tt]] >= a[i]) tt --; // 如果大于当前值则弹出

        q[++ tt] = i;
        if (i >= k - 1) printf("%d ", a[q[hh]]);
    }

    return 0;

}

0 评论

App 内打开
你确定删除吗?
1024
x

© 2018-2025 AcWing 版权所有  |  京ICP备2021015969号-2
用户协议  |  隐私政策  |  常见问题  |  联系我们
AcWing
请输入登录信息
更多登录方式: 微信图标 qq图标 qq图标
请输入绑定的邮箱地址
请输入注册信息