NC50528 滑动窗口
NC50528 滑动窗口
题目
题目描述
给一个长度为N的数组,一个长为K的滑动窗体从最左端移至最右端,你只能看到窗口中的K个数,每次窗体向右移动一位,如下图:
你的任务是找出窗体在各个位置时的最大值和最小值。
输入描述
第1行:两个整数N和K;
第2行:N个整数,表示数组的N个元素 (\(≤2 \times10^9\));
输出描述
第一行为滑动窗口从左向右移动到每个位置时的最小值,每个数之间用一个空格分开;
第二行为滑动窗口从左向右移动到每个位置时的最大值,每个数之间用一个空格分开。
示例1
输入
8 3
1 3 -1 -3 5 3 6 7
输出
-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\) 。
题解
思路
知识点:单调队列。
这是一道经典的单调队列的题,要求我们获得固定长度的所有子区间的最大/最小值,单调队列一般用 \(deque\) 实现。
获得一个区间的最大/最小值十分容易,只要遍历一遍就行。但是,发现如果改变区间哪怕是一点点,都要重新遍历,时间成本十分大。这时候就要用单调队列,其维护了一个区间的最值元素以及可能成为未来最值的元素。在常数时间内,单调队列利用旧区间已知的可能成为最值的元素和新加入的一个元素比较,来更新新区间的最值元素和可能成为未来最值的元素。
以单调递减队列维护最大值为例:
因为区间是移动的,每次移动后第一步就是判断队头最大值是否移出区间,决定是否弹出队头。
将新元素加入队列之前,会将其前方所有比他小的元素弹出,因为这些较小的旧元素是不可能成为未来区间最大值。
原因是,如果未来区间包括这些较小的旧元素,则必然包括较大的新元素,所以他们不可能成为最大值或是未来区间的最大值。正是这个操作,使得队列有了单调的性质。
完成上面两步,此时队头就是当前区间的最大值,剩余元素是未来改变区间后可能成为最大值的元素。
为了方便检查元素的在序列中位置,一般存入元素的下标。
时间复杂度 \(O(n)\)
空间复杂度 \(O(n)\)
代码
#include <bits/stdc++.h>
using namespace std;
int a[1000007];
///用单调队列维护区间最大值,队首是目前区间最大的,其他元素是未来候选最大元素,而且要满足递减。
///因为新出现某个元素,能直接弹出旧的所有较小元素,旧的较大元素能被保留,然后入队尾。
///前者原因是,包括这个元素的区间,旧的较小元素没有影响力;
///之后的区间,旧的较小元素还会比这个元素提前出区间,对后面的区间也没有影响力,因此没有作用了直接弹出。
///后者原因是,旧的较大元素可能还是目前这些区间的最大值,还不能弹出。
///每次要检验队首元素是否出区间了,需要弹出。
///维护区间最小值同理
int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int n, k;
cin >> n >> k;
for (int i = 0;i < n;i++) cin >> a[i];
deque<int> q;
for (int i = 0;i < k - 1;i++) {
while (!q.empty() && a[q.back()] >= a[i]) q.pop_back();
q.push_back(i);
}
for (int i = k - 1;i < n;i++) {
if (q.front() <= i - k) q.pop_front();
while (!q.empty() && a[q.back()] >= a[i]) q.pop_back();
q.push_back(i);
cout << a[q.front()] << ' ';
}
cout << '\n';
q.clear();
for (int i = 0;i < k - 1;i++) {
while (!q.empty() && a[q.back()] <= a[i]) q.pop_back();
q.push_back(i);
}
for (int i = k - 1;i < n;i++) {
if (q.front() <= i - k) q.pop_front();
while (!q.empty() && a[q.back()] <= a[i]) q.pop_back();
q.push_back(i);
cout << a[q.front()] << ' ';
}
return 0;
}
NC50528 滑动窗口的更多相关文章
- [LeetCode] Sliding Window Maximum 滑动窗口最大值
Given an array nums, there is a sliding window of size k which is moving from the very left of the a ...
- TCP/IP 协议中的滑动窗口
一个例子明白发送缓冲区.接受缓冲区.滑动窗口协议之间的关系. 在上面的几篇文章中简单介绍了上述几个概念在TCP网络编程中的关系,也对应了几个基本socket系统调用的几个行为,这里再列举一个例子,由于 ...
- Storm Windowing storm滑动窗口简介
Storm Windowing 简介 Storm可同时处理窗口内的所有tuple.窗口可以从时间或数量上来划分,由如下两个因素决定: 窗口的长度,可以是时间间隔或Tuple数量: 滑动间隔(slidi ...
- lintcode 滑动窗口的最大值(双端队列)
题目链接:http://www.lintcode.com/zh-cn/problem/sliding-window-maximum/# 滑动窗口的最大值 给出一个可能包含重复的整数数组,和一个大小为 ...
- TCP 三次握手四次挥手, ack 报文的大小.tcp和udp的不同之处、tcp如何保证可靠的、tcp滑动窗口解释
一.TCP三次握手和四次挥手,ACK报文的大小 首先连接需要三次握手,释放连接需要四次挥手 然后看一下连接的具体请求: [注意]中断连接端可以是Client端,也可以是Server端. [注意] 在T ...
- tcp协议头窗口,滑动窗口,流控制,拥塞控制关系
参考文章 TCP 的那些事儿(下) http://coolshell.cn/articles/11609.html tcp/ip详解--拥塞控制 & 慢启动 快恢复 拥塞避免 http://b ...
- CodeForces 701C They Are Everywhere (滑动窗口)
题目链接:http://codeforces.com/problemset/problem/701/C 题意:找到字符串中能包含所有元素的最短字符串长度. 利用“滑动窗口”解题 解题思路: 1. 遍历 ...
- TCP协议总结--停止等待协议,连续ARQ协议,滑动窗口协议
前言:在学习tcp三次握手的过程之中,由于一直无法解释tcpdump命令抓的包中seq和ack的含义,就将tcp协议往深入的了解了一下,了解到了几个协议,做一个小结. 先来看看我的问题: 这是用tcp ...
- uva 1606 amphiphilic carbon molecules【把缩写写出来,有惊喜】(滑动窗口)——yhx
Shanghai Hypercomputers, the world's largest computer chip manufacturer, has invented a new classof ...
随机推荐
- 我的树莓派 Raspberry Pi Zero 2W 折腾笔记,记录一些遇到的问题和解决办法
0x00 前言说明 最近买了一块Raspberry Pi Zero 2W来玩,目的是想搭建一台远程运行的个人服务器,上面放个博客.点个灯啥的.于是就有了这篇文章. 树莓派官网地址:https://ww ...
- 《图解UE4渲染体系》Part 1 多线程渲染
上回书<Part 0 引擎基础>说到,我们粗略地知道UE4是以哪些类来管理一个游戏场景里的数据的,但这仅仅是我们开始探索UE4渲染体系的一小步. 本回主要介绍UE4渲染体系中比较宏观顶层的 ...
- 【图解】面试题:ConcurrentHashMap是如何保证线程安全的
注意:JDK1.7与JDK1.8中的ConcurrentHashMap主要延续HashMap的设计与思想,是在其基础上进行的相应优化 1.JDK1.7中的底层实现原理 (1)JDK1.7Concurr ...
- netty系列之:netty中的frame解码器
目录 简介 LineBasedFrameDecoder DelimiterBasedFrameDecoder FixedLengthFrameDecoder LengthFieldBasedFrame ...
- 华硕主板安装Ubuntu双系统无法启动解决办法
问题描述: 在安装完Ubuntu后,开机后没有启动项可以选择,而是直接进入win10系统. 解决办法: 开机进入bios,选择 高级模式 (Advance model),进入 启动(boot)选项卡, ...
- PHP代码审计之命令注入攻击
PHP漏洞-命令注入攻击 命令注入攻击 PHP中可以使用下列5个函数来执行外部的应用程序或函数 system.exec.passthru.shell_exec.``(与shell_exec功能相同) ...
- CesiumJS 2022^ 原理[4] - 最复杂的地球皮肤 影像与地形的渲染与下载过程
目录 API 回顾 1. 对象层级关系 1.1. Scene 中特殊的物体 - Globe 1.2. 地球 Globe 与椭球 Ellipsoid 1.3. 瓦片四叉树 - QuadtreePrimi ...
- 基于.NetCore开发博客项目 StarBlog - (5) 开始搭建Web项目
系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...
- 面试官问:Go 中的参数传递是值传递还是引用传递?
一个程序中,变量分为变量名和变量内容,变量内容的存储一般会被分配到堆和栈上.而在 Go 语言中有两种传递变量的方式值传递和引用传递.其中值传递会直接将变量内容附在变量名上传递,而引用传递会将变量内容的 ...
- python基础与数据类型(int, float, str, list)
目录 python多版本共存 在cmd窗口进入不同版本的python环境 在pycharm中切换不同的版本 python语法之注释 python变量与常量 变量 变量的本质 变量的命名规范 常量 py ...