单调队列与滑动窗口(Sliding window, poj2823)
来源:互联网 发布:php音乐分享网站源码 编辑:程序博客网 时间:2024/04/28 06:11
单调队列,顾名思义,就是(严格)单调(递增或递减)的队列。下面以单调递减队列为例。
单调递减队列:
1.单调递减的队列,队首元素总是最大的。
2.元素只能从队尾入队,但可以从队尾或队首出队。若待入队的元素>=队尾元素,队尾元素出队,直到待入队的元素<队尾元素,或队列为空,然后待入队的元素从队尾入队;若新入队的元素与队首元素的距离>=窗口宽度,说明队首元素已不在窗内,队首元素出队。
3.单调队列有两个单调性:(1)元素的值是严格单调的,这里是严格单调递减;(2)元素的下标总是严格单调递增的。
举个例子,有8个元素1, 3, -1, -3, 5, 3, 6, 7,窗口的宽度是3,沿着排列滑动,输出每个窗口的最大值。
例如,1, [3, -1, -3,] 5, 3, 6, 7,窗口中的三个元素是3, -1, -3,最大值是3。
于是,输出的值依次是3, 3, 5, 5, 6, 7。
题目是给定n个元素,窗口宽度是m,随着窗口的滑动,依次输出窗中元素的最大值和最小值。
我的算法是,首先对前m个元素由小到大排序,于是最小值是排序后数列的头元素,最大值是尾元素。移动窗口至下一格,排序好的数列插入一个元素,删除一个元素,仍然保持单调性,于是最小值仍然是头元素,最大值仍然是尾元素。搜索的时间复杂度是lgm(二分查找),插入/删除的时间复杂度是1(memcpy),进行n-m+1次,于是算法的时间复杂度是O(nlgm)。
下面用单调递减队列解决,仍然以1, 3, -1, -3, 5, 3, 6, 7为例。
队列为空,1直接入队。1
下一个元素3,大于1,1出队,3入队。3
下一个元素-1,小于3,-1入队。3, -1
下一个元素-3,小于-1,-3入队。3, -1, -3
下一个元素5,依次与队尾元素比较直到队尾元素>5或队空。于是-3, -1, 3依次出队,5入队。5
下一个元素3,小于5,入队。5, 3
下一个元素6,3, 5依次出队,6入队。6
下一个元素7,6出队,7入队。7
考察单调队列队首元素,可得3, 3, 5, 5, 6, 7。
下面是单调递减队列的代码。
int inputque[MAXN] //输入序列int indexque[MAXN] //单调队列,事实上保存的是元素下标int maxout[MAXN] //输出窗内元素的最大值int rear=-1, front=0; //初始化队列为空。当rear+1 == front,队列为空;若rear==front,队列中只有一个元素。for (int i=0; i<MAXN; ++i) //遍历输入队列,i为当前下标{ if (rear+1 == front) indexque[++rear] = i; //若队列为空,直接入队 else { while (inputque[i] >= inputque[indexque[rear]] && rear>=front) --rear; //若队尾元素<=当前元素且队列不为空,队尾元素出队直到... indexque[++rear] = i; //当前元素入队 if (i - indexque[front] == m) ++front; //若队首元素已不在窗内,即当前元素的下标与队首元素的下标之差超过m,队首元素出队 } maxout[i] = inputque[indexque[front]]; //输出单调队列队首元素,即最大元素。}初始输入序列的大致每个元素都入队一次、出队一次,这两个操作都消耗常数时间,所以时间复杂度为O(n),即线性时间复杂度。
0 0
- 单调队列与滑动窗口(Sliding window, poj2823)
- Sliding Window poj2823--单调队列
- POJ2823 Sliding Window单调队列
- POJ2823 Sliding Window(单调队列)
- POJ2823 Sliding Window(单调队列)
- 单调队列 poj2823 Sliding Window
- POJ2823 Sliding Window(单调队列)
- 【POJ2823】Sliding Window-单调队列
- poj2823 Sliding Window 单调队列
- poj2823 Sliding Window 单调队列
- [POJ2823]Sliding Window(单调队列)
- [POJ2823]Sliding Window(单调队列)
- POJ2823 Sliding Window【单调队列】
- 单调队列--poj2823 Sliding Window
- sliding window 滑动窗口(单调队列)
- POJ2823 Sliding Window,手工实现单调队列
- POJ2823:Sliding Window(单调队列||线段树)
- poj2823--Sliding Window--线段树||单调队列
- jQuery填充剩余宽度
- freemarker 介绍 入门
- javacript之switch
- 幸福女人不可缺少8种朋友
- Opencv4Android安装终于成功,分享安装过程中的bug。
- 单调队列与滑动窗口(Sliding window, poj2823)
- CListCtrl的用法
- linux下IPTABLES配置详解
- Mysql 中使用DATE_FORMAT函数按月、周统计数据
- 十四章--icloud技术--之二
- Unable to execute dex: Multiple dex files define 解决方法 (转)
- andengine背景滚动循环AutoParallaxBackground
- Git fetch和git pull的区别
- 图像处理基础(一)_图像的像素是什么?