首页 > 编程语言 >基础算法——单调栈和单调队列的最常用考法

基础算法——单调栈和单调队列的最常用考法

时间:2024-11-22 21:46:03浏览次数:3  
标签:队列 tt ++ while int hh 单调 考法

单调栈和单调队列虽然有点抽象但在算法题中很少涉题。

单调栈常见的最可能考的就是:给定一个序列,求序列当中每一个数左边离他最近的数,且比他小(大)的数在什么地方,对称下就可类比为右边最近比他(大或小的数)。

首先想到暴力做法;两重循环,i枚举每个数,j从 i-1开始往左边找第一个比a[i]小的,时间复杂度为O(n2),很大可能会超时。

单调栈优化的话:i指针每往右边移动时,把每个数存到栈里,把目光放到栈里,将数在栈中操作,这样每个数操作一次就行了,整体时间复杂度就是O(n)

具体题目要求:
给定一个长度为 N
的整数数列,输出每个数左边第一个比它小的数,如果不存在则输出 −1

#include<iostream>

using namespace std;

const int N = 100010;
int st[N];//模拟栈
int tt;//栈尾指针

int main(){
    
    int n;//长度为n的数列
    scanf("%d",&n);
    for(int i = 0; i < n; i++){
        int x;
        scanf("%d",&x);//输入次数,目的是找到左边第一个比他小的数
        
        //当栈不为空且栈顶元素大于等于次数时,出栈。直到栈顶元素小于次数,栈顶元素即为所求
        while(tt && st[tt] >= x)tt--;
        
        if(tt > 0) printf("%d ",st[tt]);
        else printf("-1 ");
        //求出此次比他小的数后,将该数也添加到栈中
        st[++tt] = x;
    }
    return 0;
}

单调队列应用最典型的问题就是:滑动窗口:求窗口中的最大值或最小值输出。

#include<iostream>

using namespace std;

const int N = 1000010;

int a[N],q[N];
//a数字存储元素,q数组存储下标
int n,k;
int main(){

    scanf("%d %d" ,&n,&k);
    for(int i = 0; i < n; i++) scanf("%d",&a[i]);
    //最窗口最小值
    int hh = 0, tt = -1;
    for(int i = 0; i < n; i++){

        while(hh <= tt && i-k+1 > q[hh])hh++;

        while(hh <= tt && a[q[tt]] >= a[i]) tt--;
        q[++tt] = i;
        if(i >= k -1) printf("%d ",a[q[hh]]);
    }
    puts("");

    //求窗口最大值
    hh = 0, tt = -1;
    for(int i = 0; i < n; i++){
        while(hh <= tt && i-k+1 > q[hh])hh++;

        while(hh <= tt && a[q[tt]] <= a[i]) tt--;
        q[++tt] = i;
        if(i >= k -1) printf("%d ",a[q[hh]]);
    }    
    puts("");
    return 0;

}

标签:队列,tt,++,while,int,hh,单调,考法
From: https://blog.csdn.net/wangsongstc/article/details/143838669

相关文章

  • 代码随想录第十天|栈与队列part01--栈与队列理论基础、225.用队列实现栈、232.用栈实
    资源引用:栈与队列理论基础(栈与队列理论基础)leetcode题目:225.用队列实现栈(225.用队列实现栈)232.用栈实现队列(232.用栈实现队列)20.有效的括号(20.有效的括号)1047.删除字符串中的所有相邻重复项(1047.删除字符串中的所有相邻重复项)久违碎碎念:“放弃不可怕,可怕的是没有继续......
  • 入门RTOS第七篇(队列函数)
    1.使用队列的流程:创建队列,写队列,读队列,删除队列2.创建队列有两种方法:动态分配内存、静态分配内存函数原型如下:QueueHandle_txQueueCreate(UBaseType_tuxQueueLength,UBaseType_tuxItemSize);静态分配内存:xQueueCreateStatic,队列的内存要事先分配好函数原型如下:Qu......
  • 消息队列-知识点
    消息队列概念:一个存放消息的容器,当系统需要使用消息的时候,直接从容器中按照先进先出的顺序,取出消息供系统使用。参与消息传递的双方称为生产者和消费者,生产者负责发送消息,消费者负责处理消息。作用异步处理削峰/限流降低系统耦合性异步处理将用户请求中包含的耗......
  • 队列
    前言先进先出,没啥好说的STLqueue#include<bits/stdc++.h>usingnamespacestd;intmain(){queue<int>q;q.push(12);//12进入队列q.push(13);//13进入队列q.push(123);//123进入队列cout<<......
  • 【c++丨STL】priority_queue(优先级队列)的使用与模拟实现
    ......
  • 轻质感UI界面肯定会流行的,简约不单调,真实又不复杂。
    轻质感UI界面有着独特的魅力,它代表着未来设计的趋势。这种界面以简约为核心,摒弃了繁琐的装饰元素,却丝毫不会让用户感到单调。通过巧妙运用色彩的深浅变化、柔和的光影效果和简洁的几何图形,营造出一种清新自然又时尚的氛围。比如,使用淡淡的渐变色来区分不同功能区域,用简约的......
  • 用Redis实现去重的任务队列的多种方案
    前情提要:一点小小的不完善的方案的思考和设计,不对的地方或是更好的方案欢迎大佬们在评论区讨论~需求背景:在Redis里使用List数据结构做任务队列,但是有的时候任务可能会重复添加,所以需要进行去重。队列需要有优先级,尽量减少Redis操作次数。尝试方案目前能够想到的方案......
  • 【数据结构】栈和队列的定义与实现
    主页:HABUO......
  • 前K个高频元素——栈与队列
    先放代码:classSolution{public:classmycomperation{public://注意这里的问题booloperator()(constpair<int,int>&lhs,constpair<int,int>&rhs){returnlhs.second>rhs.second;}};vect......
  • 滑动窗口最大值——栈与队列
    第一版代码:classSolution{private:classMyQueue{//单调队列(从大到小)public:deque<int>que;//使用deque来实现单调队列//每次弹出的时候,比较当前要弹出的数值是否等于队列出口元素的数值,如果相等则弹出。//同时pop之前判断队列当......