AcWing - 滑动窗口(单调队列)
发布日期:2021-07-01 00:21:59
浏览次数:3
分类:技术文章
本文共 2256 字,大约阅读时间需要 7 分钟。
题目链接:
时/空限制:1s / 64MB题目描述
给定一个大小为n≤106的数组。
有一个大小为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 |
您的任务是确定滑动窗口位于每个位置时,窗口中的最大值和最小值。
输入格式
输入包含两行。
第一行包含两个整数n和k,分别代表数组长度和滑动窗口的长度。
第二行有n个整数,代表数组的具体数值。
同行数据之间用空格隔开。
输出格式
输出包含两个。
第一行输出,从左至右,每个位置滑动窗口中的最小值。
第二行输出,从左至右,每个位置滑动窗口中的最大值。
输入样例
8 3
1 3 -1 -3 5 3 6 7
输出样例
-1 -3 -3 -3 3 3
3 3 5 5 6 7
解题思路
题意:给你一个长度为n的序列,长度为k的窗口在上面向右移动,求出每次移动时窗口内数字的最小值和最大值。
思路:维护两个队列,一个是最小值,一个是最大值。以最小值为例,最大值同理。 求最小值:建立一个单调递增队列,元素从左到右依次入队,入队之前必须从队列尾部开始删除那些比当前入队元素大或者相等的元素,直到遇到一个比当前入队元素小的元素,或者队列为空为止。此时队列中剩下的元素严格单调递增,所以队头就是整个队列中的最小值,若此时队头元素不在窗口中,则从队头删除元素,直到队头在窗口中为止。然后把当前元素插入队尾。Accepted Code:
/* * @Author: lzyws739307453 * @Language: C++ */#includeusing namespace std;const int MAXN = 1000005;struct Queue { int data[MAXN]; int front_, rear; Queue() { front_ = 0, rear = -1; } void push(int x) { data[++rear] = x; } void pop_front() { front_++; } void pop_back() { rear--; } int front() { return data[front_]; } int back() { return data[rear]; } int size() { return rear - front_ + 1; } bool empty() { return rear < front_; }}Qmin, Qmax;int cnt_max = 0, cnt_min = 0;int spt[MAXN], res_max[MAXN], res_min[MAXN];int main() { int n, m; scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) scanf("%d", &spt[i]); for (int i = 1; i <= n; i++) { while (!Qmax.empty() && Qmax.front() + m - 1 < i) Qmax.pop_front(); while (!Qmin.empty() && Qmin.front() + m - 1 < i) Qmin.pop_front(); while (!Qmax.empty() && spt[Qmax.back()] <= spt[i]) Qmax.pop_back(); while (!Qmin.empty() && spt[Qmin.back()] >= spt[i]) Qmin.pop_back(); Qmax.push(i), Qmin.push(i); res_max[++cnt_max] = Qmax.front(); res_min[++cnt_min] = Qmin.front(); } for (int i = m; i <= n; i++) printf("%d%c", spt[res_min[i]], "\n "[i != n]); for (int i = m; i <= n; i++) printf("%d%c", spt[res_max[i]], "\n "[i != n]); return 0;}
转载地址:https://lzyws739307453.blog.csdn.net/article/details/99974192 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
关注你微信了!
[***.104.42.241]2024年04月26日 12时22分28秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
[10] JMeter-察看结果树,你知道都有哪些功能吗?
2021-07-04
[11] JMeter-结果分析之聚合报告
2021-07-04
[12] JMeter-结果分析之图形图表
2021-07-04
[13] JMeter-详解JMeter参数化之CSV Data Set Config
2021-07-04
[14] JMeter关联-详解JMeter正则表达式提取器
2021-07-04
优化jmeter脚本
2019-05-01
Gradle基础使用总结1
2019-05-01
性能测试场景设置---不同场景下对应的jmeter脚本【不定时补充】
2019-05-01
登录oracle数据库时常用的操作命令整理
2019-05-01
微信小程序实现安卓机下拉不刷新,ios下拉刷新操作(自定义底部tab栏在安卓机下拉)
2019-05-01
小程序动态获取组件高度(自定义Tabbar的高度)
2019-05-01
如何是实现微信会员开卡组件中一个手机号绑定一个微信号(思路篇)
2019-05-01
小程序实现sku商品规格
2019-05-01
has been blocked by CORS policy: Response to preflight request doesn‘t pass access control check 报错
2019-05-01
使用aspose.words 18.6实现pdf文档转换
2019-05-01
包机制介绍
2019-05-01