博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
单调栈与单调队列
阅读量:5160 次
发布时间:2019-06-13

本文共 1020 字,大约阅读时间需要 3 分钟。

前置知识:

  

  队列

单调栈

  思考这样一个问题:给定一个数列,询问每一个数左边的第一个比它小的数。

  暴力的做法是:记录下所有读进来的数,然后,每次向前查找,预计时间复杂度O(n2),而且容易被卡。

  仔细思考一下,可以发现,这个做法之所以效率低下,是因为每一次都重复查找了许多肯定不是最优解的元素。很明显,如果当前查找时这个元素不是最优解,那么在之后的查找中它也不会是最优解。我们可以用一个栈来维护:每一次把不是最优解的元素出栈,然后把当前的元素加入栈中。由于每个元素最多进栈一次、出栈一次,因此这个算法的效率是O(n)的。

  上例中,我们使用的这个栈就是一种简单的单调栈。单调栈中的元素具有单调性,而为了保证这一点,在元素加入栈中前需要把栈中所有破坏单调性的元素删除。

  如果从正反两个方向各扫一遍单调栈,可以处理出每个元素在哪一段区间中是最小的。

  放上代码:

int n,top,a[N],b[N];//a[N]为原序列,b[N]记录维护的答案 struct node{    int pos,val;}q[N];//单调栈:pos记录在原序列中的位置,val记录权值 void work(){    for(int i=1;i<=n;i++){        while(top&&q[top].val

 

单调队列

  单调队列与单调栈的原理是一样的。但它还可以通过移动头指针来及时排除那些已在范围之外的答案以保证最终答案的正确性。同单调栈一样,由于每个元素最多入队一次、出队一次,单调队列的效率也是O(n)的。

  放上代码:

int n,k,l,r,d[N],a[N],b[N];//k为指定的区间长struct node{    int pos,val;}q[N];void work(){    l=1,r=0;    for(int i=1;i<=n;i++){        while(q[l].pos
<=r) l++;//先调整队首指针以排除非法答案 while(a[i]>=q[r].val&&l<=r) r--;//维护单调性 q[++r].pos=i;q[r].val=a[i];b[i]=q[l].val; }}

 

 

 

转载于:https://www.cnblogs.com/doyo2019/p/10778855.html

你可能感兴趣的文章
libnet/libnids库函数介绍
查看>>
saveInstallState参数使用详解(android activity状态保存和恢复)
查看>>
mark
查看>>
HTTP header
查看>>
AVD启动不了 ANDROID_SDK_HOME is defined but could not find *.ini
查看>>
1~4次
查看>>
ubuntu18.04更新源
查看>>
大道至简第七、八章 读后随笔
查看>>
react 反模式——不使用jsx动态显示异步组件
查看>>
Linux下用文件IO的方式操作GPIO(/sys/class/gpio)
查看>>
Eclipse快捷键
查看>>
CentOS下配置SMTP
查看>>
Centos7中查看IP地址命令ifconfig无法识别如何处理
查看>>
Longest Consecutive Sequence
查看>>
python --001 -- 基础小知识
查看>>
P2P简单应用之通信协议介绍
查看>>
HOMEWORK2
查看>>
python与ruby的差别
查看>>
capture同focus
查看>>
卡尔曼滤波算法--核心公式推导导论 - ZZ
查看>>