I - 滑动窗口

题目

原题来自:POJ 2823

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

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

输入格式

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

输出格式

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

样例

Input

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

Output

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

数据范围与提示

对于 20% 的数据,K≤N≤1000;
对于 50% 的数据,K≤N≤10^5;
对于 100% 的数据,K≤N≤10^6。

思路

该题为单调队列的典型题。

如果纯暴力做的话,我们要从第一个元素一直历到第N个元素,每遍历一个元素都要再遍历框里面的元素,找出框里面的最大或最小值,这样的时间复杂是O(N×K)了,对于N和K都等于10^6时,时间已经爆了,所以我们要想一个更快速的做法,单调队列就是一个不错的选择。

就以样例中求每个框中的最小值为例:

单调队列首先要设头指针和尾指针(此指针非彼指针),还要建立一个队列数组,要注意的是队列数组中存的是元素的下标,而不是元素的值。

当框内元素还没到K个的时候,无法求得框内的最小值

当框移动到 i=3 的位置时

这时框内的最小值为-1,可存入队列中 ,这时候头指针指向了1,尾指针指向了2

当框移动到 i=4 的位置时

这时候新来的元素 -3 比头指针指向的 -1 还要小,所以要把 -1 踢出队列,踢出队列的方法就是让尾指针往前一格,这样下一次记录的时候就会将 -1 覆盖掉,就相当于把 -1 踢出去了

如此操作后队列就变成了

当框移动到 i=5 的位置时

这时候新来的元素是 5 ,比 -3 大,所以按从小到大的队列顺序来排应该排到后面,只需将 5 正常插入进队列即可

如此操作后队列就变成了

当框移动到 i=6 的位置时

这时候新来的元素是 3 ,比 -3 大,但比 5 要小,按顺序应该排到 5 前面,但是按照队列先进先出的特性,我们应该先把 5 踢出去,然后才能把 3 放进来,所以就按之前的操作一样,让尾指针往前走一格,然后将 3 存入即可

如此操作后队列就变成了

当框移动到 i=7 的位置时

要注意的是这个时候 -3 已经不在框里面了,所以我们要将 -3 给踢出去,方法就是将头指针向后走一格,这样 -3 就不在队列的范围里面了,然后新来的元素是 6 ,比 3 大,所以排到3的后面

如此操作后队列就变成了

有些同学看到这里可能就会有疑问了,之前的 -1 去哪了?为了解决这个问题,我们进行实时输出就行了

if (i >= k)
{cout << a[q[head]] << " ";
}

再次提醒一下,队列 q 里面存的是元素的下标,所以输出队列内元素的时候是输出 a[q[head]]

同样的,求题目中要求的最大值就令队列的排序规则反过来即可,该方法的时间复杂度为O(N)。

代码

#include<iostream>
using namespace std;
int n, k, a[1000005], q[1000005], head, tail;
int main()
{cin >> n >> k;for (int i = 1; i <= n; ++i){cin >> a[i];}head = 1, tail = 0;for (int i = 1; i <= n; ++i){if (head <= tail && i - k + 1 > q[head])//头指针肯定在尾指针前面{++head;}while (head <= tail && a[i] < a[q[tail]]){--tail;}q[++tail] = i;//这里存入的是元素的下标if (i >= k)//只要框到位置了,就直接输出当前状态的最小值{cout << a[q[head]] << " ";}}cout << endl;head = 1, tail = 0;//重置一下头、尾指针的位置for (int i = 1; i <= n; ++i){if (head <= tail && i - k + 1 > q[head]){++head;}while (head <= tail && a[i] >= a[q[tail]]){--tail;}q[++tail] = i;if (i >= k){cout << a[q[head]] << " ";}}return 0;
}

GDUT - 专题学习1 I - 滑动窗口相关推荐

  1. VINS-MONO学习笔记 [基于滑动窗口的非线性优化]

    目录 1. 代码 2. ceres解析求导 3. ceres李代数加法代码实现 4. 预积分约束残差计算 5. 预积分雅克比计算 6. 视觉重投影约束 7. 滑动窗口边缘化 1. 代码 代码位置: v ...

  2. GDUT - 专题学习3 G - 食物链

    题目 如图所示为某生态系统的食物网示意图,据图回答此题. 现在给你 n 个物种和 m 条能量流动关系,求其中的食物链条数. 物种的名称为从 1 到 n 的编号. mm 条能量流动关系形如 a1​ b1 ...

  3. GDUT - 专题学习1 C - 马走日

    C - 马走日 题目 马在中国象棋以日字形规则移动. 请编写一段程序,给定 n×m 大小的棋盘,以及马的初始位置 (x,y),要求不能重复经过棋盘上的同一个点,计算马可以有多少途径遍历棋盘上的所有点. ...

  4. GDUT - 专题学习1 A - Red and Black

    A - Red and Black 题目 There is a rectangular room, covered with square tiles. Each tile is colored ei ...

  5. GDUT - 专题学习1 D - 一维前缀和

    D - 一维前缀和 题目 一天,在宿舍睡觉的你,突然梦到了游戏之神,他说:去玩<极限脱出>吧,这部作品的剧情和世界观绝对会带来很大的震撼,值得一玩. 对了,这部作品的第一代发布在nds上, ...

  6. GDUT - 专题学习2 C - 开餐馆

    C - 开餐馆 题目 蒜头君想开家餐馆. 现在共有 n 个地点可供选择.蒜头君打算从中选择合适的位置开设一些餐馆.这 n 个地点排列在同一条直线上.我们用一个整数序列 m1​,m2​,...mn​ 来 ...

  7. 3.4 滑动窗口的卷积实现-深度学习第四课《卷积神经网络》-Stanford吴恩达教授

    ←上一篇 ↓↑ 下一篇→ 3.3 目标检测 回到目录 3.5 Bounding Box 预测 滑动窗口的卷积实现 (Convolutional Implementation of Sliding Wi ...

  8. 计算机网络学习笔记(四)——差错控制、停等协议、回退N帧、选择性重传、滑动窗口、数据链路层HDLC、PPP协议、有限状态机

    文章目录 前言 概念 一.差错控制 1.停等协议 2.回退N帧协议(GoBack_N,GB_N) 3.选择性重传协议(Selective Repeat,SR) 4.单帧确认和累计确认.捎带应答 二.链 ...

  9. 深度学习笔记(35) 滑动窗口的卷积实现

    深度学习笔记(35) 滑动窗口的卷积实现 1. 卷积实现 2. 减少计算成本 1. 卷积实现 为了构建滑动窗口的卷积应用,首先要知道如何把神经网络的全连接层转化成卷积层 假设对象检测算法输入一个14× ...

最新文章

  1. 用 PHP 调用 MySQL 存储过程
  2. adb 重命名_Linux操作系统:三种最基本的文件重命名方法
  3. linux交换分区的文件格式为,LINUX的交换分区或交换文件SWAP的查看与维护
  4. 分布式链路追踪框架的基本实现原理
  5. Python内置数据类型之Dict
  6. java 生产者消费者_Java多线程:线程间通信—生产者消费者模型
  7. linux防火墙知识,Iptables防火墙 基础知识
  8. caffe之 Blob、Layer、Net
  9. 使用cmd命令创建vue(ivieiw)项目
  10. Java知识系统回顾整理01基础01第一个程序05Eclipse中运行Java程序
  11. 12306 官网硬卧下铺的选择
  12. mac airdrop 隔空投送 我可以发现别人,别人发现不了我。搜索不到。
  13. 电脑软件:推荐两款好用的文件重复检测软件,赶快给你的电脑瘦瘦身吧!
  14. STM8单片机的启动过程。
  15. 武林外传服务器时间修改,浅谈武林外传关于2021年4月29日大合区
  16. 如何关闭计算机自动关机设置方法,Win7电脑怎么取消自动关机?
  17. vm怎么上传镜像文件到服务器,vmware怎么添加iso镜像文件-vmware添加iso镜像文件的方法 - 河东软件园...
  18. 敏捷概念.Stacey矩阵
  19. 电脑调节屏幕亮度快捷键失灵の解决方案
  20. php 考试系统 倒计时,php实现倒计时效果_PHP

热门文章

  1. 响应式网站-- css媒体查询 字体大小
  2. 什么软件支持什么格式
  3. python unicode转字符串_Python: 在Unicode和普通字符串之间转换
  4. ​嘉楠往事:浮沉八载,如今剑指美股
  5. 华硕EeePC: 没有光驱重装系统(用U盘作为电脑启动盘)
  6. 视频教程-Spring Boot实战入门视频课程-Java
  7. Ubuntu20.04桌面系统快速上手教程
  8. Python3.7.4入门-4模块
  9. 第一章 数据结构与算法-前言
  10. 互联网与信息安全 ——云计算及其安全