首页 > 其他分享 >通关数据结构 day_05 -- 单调队列

通关数据结构 day_05 -- 单调队列

时间:2022-10-11 16:57:08浏览次数:67  
标签:队列 窗口 05 -- 最小值 int hh 滑动 day

单调队列

经典应用:滑动窗口里的最大值/最小值

举例

假设有序列:

1 3 -1 -3 5 3 6 7

第一次滑动窗口是 【1 3 -1】最小值是 -1

第二次滑动窗口是 【3 -1 -3】最小值是 -3

以此类推最后一次滑动窗口是 【3 6 7】 最小值是 3

我们用队列来维护这个窗口,保证队列中存储的时时刻刻都是我们窗口中的元素

每一次求极值的时候,暴力做法是遍历窗口中的元素,时间复杂度是O(k)

单调队列定律:当一个选手比你小还比你强的时候,你永远无法超越他

那么只要我们的队列中存在如下情况:

前面有一个数,比我后面的数大,那么前面的点一定没有用

因此,我们就可以把大的点删了,最后会变成一个严格单调上升的队列

模板

常见模型:找出滑动窗口中的最大值/最小值
int hh = 0, tt = -1;
for (int i = 0; i < n; i ++ )
{
    while (hh <= tt && check_out(q[hh])) hh ++ ;  // 判断队头是否滑出窗口
    while (hh <= tt && check(q[tt], i)) tt -- ;
    q[ ++ tt] = i;
}

练习

154. 滑动窗口 - AcWing题库

给定一个大小为 n≤106 的数组。

有一个大小为 k 的滑动窗口,它从数组的最左边移动到最右边。

你只能在窗口中看到 k个数字。

每次滑动窗口向右移动一个位置。

以下是一个例子:

该数组为 [1 3 -1 -3 5 3 6 7],kk 为 33。

窗口位置 最小值 最大值
[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
#include<iostream>
using namespace std;

const int N = 1000010;
int n,k;
int a[N],q[N];

int main()
{
    cin.tie(0);
    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]] << " ";
        }
        
    }
    
    cout << endl;
    
    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;
}

标签:队列,窗口,05,--,最小值,int,hh,滑动,day
From: https://www.cnblogs.com/ShibuyaKanon/p/16779750.html

相关文章

  • 39. JS动画效果的实现(附带示例)
    1.前言在学习CSS时我们知道,通过CSS可以实现简单的动画效果,但对于比较复杂的动画,使用CSS实现起来就会比较麻烦。除了可以使用CSS来实现外,也可以使用JavaScript......
  • Java注解
    Java注解注解Annotation//自定义注解必须是在@interface//如下自定义注解Report//default用于给注解参数设置默认值public@interfaceReport{inttype()de......
  • 分离部署LNMP架构
    分离部署LNMP目录分离部署LNMP部署nginx部署mysql部署php安装后配置nginx服务器端php端配置环境说明:系统主机名IP服务centos8nginx192.168.111.141nginx......
  • 初识node.js[1]
    一、浏览器中JavaScript组成部分JS核心语法【变量、数据类型;循环、分支、判断;函数、作用域、this;etc...】WebApi【DOM;BOM;Ajax;...】为什么JavaScript可以在浏览器内运行......
  • 514多表关系多对多关系实现和515多表关系一对一关系实现
    多对多关系实现1.如学生和课程,分析: 多对多关系实现需要借助第三张中间表。中间表至少包含两个字段,这两个字段作为第三张表的外键,分别指向两张表的主键  一对一关......
  • Redis主从复制
    1、主从复制单个Redis如果因为某种原因宕机的话,可能会导致Redis服务不可用,可以使用主从复制实现一主多从,主节点负责写的操作,从节点负责读的操作,主节点会定期将数据同......
  • 【新技术】不用开发者账号申请ios证书真机调试
     虽然xcode现在可以免证书进行测试了,但众多跨平台开发者,如果还没注册苹果开发者账号。想安装到自己非越狱手机测试是无能为力了。不过新技术来了,只需要普通免费的......
  • 黑板行为树
    在黑板中用黑板拾取器拾取数据要匹配数据ID(关联黑板数据)用重写initfromset()   ......
  • 单独设置表格某行的行宽
                 选中单独要设置的列宽的单元格,鼠标放在左(右)边框上左右拖动即可。......
  • 企业应用大数据开源框架的意义何在?
    随着互联网技术的进步和发展,大数据开源框架成为很多企业数字化转型的利器。作为低代码开发平台,大数据开源框架拥有高效、灵活、便利等诸多优势特点,是为企业实现赋能、朝着......