给定一个大小为n≤106n≤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

这题我们可以使用数组模拟队列来进行求解,每次对queue维护,我们对这串数从左到右遍历,想象一个长度为k的窗口在上面不断的向右滑动~

而在这个窗口中(以最小值为例),我们每次入队一个数,如果有Ai>Aj && i<j,那么我们永远都不可能用到Ai,就将Ai出队(即弹出Aj前面所有比Aj大的数),那么我们所得的queue就是一个严格单调递增的队列,每次输出队首即可

我个人认为这段代码最难理解的是:当窗口划过时,如何去更新queue,可以这样理解,queue中的首项永远是我们窗口里面最小值的位置,如果我们遍历i的时候找到了比queue首项位置上更小的数,就将这个数的位置,更新成queue的首项,否则就一直在queue的队尾加数,而当我当前遍历到的位置i,i-k+1>q[hh],也就是说在极限情况时,q[hh]是窗口左边框,i是窗口的右边框,就需要将h++来维护队列.

具体操作:

 1 3 -1 -3 5 3  6 7

第一步:将 1 入队,hh=0,q[0]=0;

第二步:1<3,将 3 入队, hh=0 ,q[0]=0,q[1]=1;

第三步:3>-1, 前面的数都出队,将 -1 入队, hh=0, q[0]=2, 输出a[2]=-1;

第四步:-1>-3, 前面的数都出队, 将-3入队,hh=0, q[0]=3, 输出a[3]=-3;

第五步:-3<5, 将 5 入队, hh=0, q[0]=3,q[1]=4, 输出a[3]=-3;

第六步:5>3, 将5出队, 3入队,hh=0, q[0]=3, q[1]=5, 输出a[3]=-3;

第七步:3<6,将6入队,此时i-k+1=4,hh++,hh=1,q[1]=5,q[2]=6, 输出a[5]=3;

第八步:6<7,将7入队, hh=1,hh=1,q[1]=5,q[2]=6,输出3;

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string.h>
#include <math.h>
#include <algorithm>
#include <stack>
#include <queue>
#include <vector>
#include <map>
#include <set>
#define ll long long
const int N=1e6+10;
using namespace std;
typedef pair<int,int>PII; int n,k;
int a[N],q[N]; int main(){
ios::sync_with_stdio(false);
cin>>n>>k;
for(int i=0;i<n;i++) cin>>a[i];
int hh=0,tt=-1;
for(int i=0;i<n;i++){
//判断队头是否已经划出窗口
if(hh<=tt && i-k+1>q[hh]) hh++;
while(hh<=tt && a[q[tt]]>=a[i]) tt--;
q[++tt]=i;
if(i>=k-1) cout<<a[q[hh]]<<' ';
}
return 0;
}

最新文章

  1. php全面获取url地址栏及各种参数
  2. pandas 透视表 pivot_table
  3. 使自定义事件支持多绑定 js
  4. 【BZOJ】【TJOI2015】线性代数
  5. ASP.NET MVC3 实例(六) 增加、修改和删除操作(二)
  6. SAML - SSO(转)
  7. powerpoint取色器有什么用|ppt取色器使用教程
  8. 【新手--android日记】实现IOS风格电话界面
  9. 苹果Swift编程语言新手教程【中国版】
  10. linux 查看进程 和 杀死进程
  11. 201521044152&lt;java程序设计&gt;第一周学习总结
  12. Node.js系列-express(上)
  13. SSIS - 2.使用脚本任务弹出对话框
  14. Scala主构造器参数是否升级为成员与是否有get/set
  15. Stream、FileStream、MemoryStream的区别
  16. MySQL忘记root密码的解决办法
  17. PC端的鼠标拖拽滑动
  18. 【转】iframe页面跳转时,导致父页面滚动!该怎么解决?
  19. Python 图示集绵
  20. WebGL模型拾取——射线法

热门文章

  1. 【Oracle】将数据库设为开机自启
  2. JMS监听Oracle AQ
  3. centos7虚拟机开启端口后 外部不能访问的问题
  4. 基于.NET Core的优秀开源项目合集
  5. 干电池升压5V,功耗10uA
  6. [CPP] STL 简介
  7. 上海某小公司面试题:synchronized锁原理
  8. 使用注解的形式对token进行验证
  9. 解决PHP无法监听9000端口问题/502错误解决办法
  10. BI学习向导文章