【蓝桥杯集训9】单调栈、单调队列(模拟栈、模拟队列)专题(3 / 3)

news2024/11/15 8:46:48

目录

单调栈模板

1、模拟栈

单调队列模板

1、模拟队列

2、双端队列

135. 最大子序和 - 前缀和+滑动窗口+单调队列


单调栈模板

什么时候用单调栈?

求序列中每一个数左边或右边第一个比它大或小的数

1、单调递增栈

在保持栈内元素单调递增前提下(如果栈顶元素大于待入栈元素,弹出栈顶),新元素入栈

 对于要入栈的元素,在对栈进行更新后,栈顶元素就是数组中左侧第一个比自己小的元素

2、单调递减栈

在保持栈内元素单调递减前提下(如果栈顶元素小于要待入栈元素,弹出栈顶),新元素入栈

 对于要入栈的元素,在对栈进行更新后,栈顶元素就是数组中左侧第一个比自己大的元素

活动 - AcWing

题目:输出每个数左边第一个比自己小的数,如果不存在则输出-1

1、模拟栈

//进栈
stk[tt++]=x;
 
//出栈
tt--;
 
//输出栈顶元素
stk[tt-1]
//模拟栈
import java.util.*;

class Main
{
    static int N=100010;
    static int[] stk=new int[N];
    static int tt;
    
    public static void main(String[] args)
    {
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        while(n-->0)
        {
            int x=sc.nextInt();
            while(tt>0&&stk[tt]>=x) tt--;
            if(tt==0) System.out.print("-1 ");
            else System.out.print(stk[tt]+" ");
            stk[++tt]=x;
        }
    }
}
import java.util.*;

class Main
{
    public static void main(String[] args)
    {
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        Deque<Integer> stk=new LinkedList<>();
        while(n-->0)
        {
            int x=sc.nextInt();
            while(!stk.isEmpty()&&stk.peek()>=x) stk.pop();
            if(stk.isEmpty()) System.out.print("-1 ");
            else System.out.print(stk.peek()+" ");
            stk.push(x);
        }
    }
}

单调队列模板

活动 - AcWing

题目:

思路:

先求最小值,维护一个单调递增的队列存下标,队头永远是最小的

如果新入队的元素≤队尾,则去掉队尾(因为只要最小的,大的没用)

如果最小值在合法的窗口内,则输出它

再求最大值,维护一个单调递减的队列存下标,队头永远是最大的

如果新入队的元素≥队尾,则去掉队尾(因为只要最大的,小的没用)

如果最大值在合法窗口内,输出

 

1、模拟队列

int q[N];
int hh=0,tt=-1;

//入队
q[++hh]=x;

//出队
hh++;

//取队头元素
q[hh];

import java.util.*;
import java.io.*;
import java.math.*;

class Main
{
    static int N=1000010;
    static int[] a=new int[N],q=new int[N];
    //队头q[hh]存最大/最小值的下标 队尾q[tt]更新为当前元素的下标
    public static void main(String[] args) throws IOException
    {
        PrintWriter wt=new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
        
        int n=rd.nextInt(),k=rd.nextInt();
        for(int i=0;i<n;i++) a[i]=rd.nextInt();
        
        int hh=0,tt=-1;
        //求窗口内最小值
        for(int i=0;i<n;i++)
        {
            if(hh<=tt&&i+1-k>q[hh]) hh++; //保证区间左侧下标合法
            while(hh<=tt&&a[q[tt]]>=a[i]) tt--; //如果队尾元素≥a[i]则删掉队尾 因为要最小的 比它大的没有用
            q[++tt]=i;
            if(i+1-k>=0) wt.print(a[q[hh]]+" "); //在合法窗口内
        }
        wt.println();
        
        hh=0;tt=-1;
        //求窗口内最大值
        for(int i=0;i<n;i++)
        {
            if(hh<=tt&&i+1-k>q[hh]) hh++; //保证区间左侧下标合法
            while(hh<=tt&&a[q[tt]]<=a[i]) tt--; //如果队尾元素≤a[i]则删掉队尾 因为要最大的 比它小的没用
            q[++tt]=i;
            if(i+1-k>=0) wt.print(a[q[hh]]+" ");
        }
        
        wt.flush();
    }
    
    static class rd
    {
        static BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));
        static StringTokenizer tk=new StringTokenizer("");
        
        static String nextLine() throws IOException
        {
            return bf.readLine();
        }
        
        static String next() throws IOException
        {
            while(!tk.hasMoreTokens()) tk=new StringTokenizer(bf.readLine());
            return tk.nextToken();
        }
        
        static int nextInt() throws IOException
        {
            return Integer.parseInt(next());
        }
        
        static double nextDouble() throws IOException
        {
            return Double.parseDouble(next());
        }
        
        static long nextLong() throws IOException
        {
            return Long.parseLong(next());
        }
        
        static BigInteger nextBig() throws IOException
        {
            BigInteger d=new BigInteger(rd.nextLine());
            return d;
        }
    }
}

2、双端队列

import java.util.*;
import java.io.*;
import java.math.*;

class Main
{
    static int N=1000010;
    static int[] a=new int[N];
    //队头q[hh]存最大/最小值的下标 队尾q[tt]更新为当前元素的下标
    public static void main(String[] args) throws IOException
    {
        PrintWriter wt=new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
        
        int n=rd.nextInt(),k=rd.nextInt();
        for(int i=0;i<n;i++) a[i]=rd.nextInt();
        
        Deque<Integer> q1=new ArrayDeque<>();
        //求窗口内最小值
        for(int i=0;i<n;i++)
        {
            if(!q1.isEmpty()&&i+1-k>q1.peekFirst()) q1.pollFirst(); //保证区间左侧下标合法
            while(!q1.isEmpty()&&a[q1.peekLast()]>=a[i]) q1.pollLast(); //如果队尾元素≥a[i]则删掉队尾 因为要最小的 比它大的没有用
            q1.offerLast(i);
            if(i+1-k>=0) wt.print(a[q1.peekFirst()]+" "); //在合法窗口内
        }
        wt.println();
        
        Deque<Integer> q2=new ArrayDeque<>();
        //求窗口内最大值
        for(int i=0;i<n;i++)
        {
            if(!q2.isEmpty()&&i+1-k>q2.peekFirst()) q2.pollFirst(); //保证区间左侧下标合法
            while(!q2.isEmpty()&&a[q2.peekLast()]<=a[i]) q2.pollLast(); //如果队尾元素≤a[i]则删掉队尾 因为要最大的 比它小的没用
            q2.offerLast(i);
            if(i+1-k>=0) wt.print(a[q2.peekFirst()]+" ");
        }
        
        wt.flush();
    }
    
    static class rd
    {
        static BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));
        static StringTokenizer tk=new StringTokenizer("");
        
        static String nextLine() throws IOException
        {
            return bf.readLine();
        }
        
        static String next() throws IOException
        {
            while(!tk.hasMoreTokens()) tk=new StringTokenizer(bf.readLine());
            return tk.nextToken();
        }
        
        static int nextInt() throws IOException
        {
            return Integer.parseInt(next());
        }
        
        static double nextDouble() throws IOException
        {
            return Double.parseDouble(next());
        }
        
        static long nextLong() throws IOException
        {
            return Long.parseLong(next());
        }
        
        static BigInteger nextBig() throws IOException
        {
            BigInteger d=new BigInteger(rd.nextLine());
            return d;
        }
    }
}

 

135. 最大子序和 - 前缀和+滑动窗口+单调队列

活动 - AcWing

题目:

输入一个长度为 n 的整数序列,从中找出一段长度不超过 m 的连续子序列,使得子序列中所有数的和最大

注意: 子序列的长度至少是 1

思路:

  • 首先求一段连续数的和,用前缀和
  • 枚举区间的右端点i,当i固定时,问题转化成:寻找一个j,使 j \in[i-m,i-1],且s[j]最小
  • 一段区间的和,可以转化为前缀和相减的形式,前缀和减去的数越小,则区间和越大
  • 对于任意的j和k,满足k<j<i,如果s[k]>=s[j],对于所有≥i的右端点,k永远不会成为最佳选择,因为不仅s[k]更大,而且k<j,长度容易超出m,因此去掉k
  • 可以维护一个单调递增的队列,队头即为最小
/*
    *道阻且长,行则将至*
    author:Roye_ack
*/
import java.util.*;
import java.io.*;
import java.math.*;

class Main
{
    static int N=300010;
    static int[] s=new int[N];
    
    public static void main(String[] args) throws IOException
    {
        PrintWriter wt=new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
        
        int n=rd.nextInt(),m=rd.nextInt();
        for(int i=1;i<=n;i++) 
        {
            s[i]=rd.nextInt();
            s[i]+=s[i-1];
        }
        
        Deque<Integer> q=new ArrayDeque<>();
        q.offerLast(0); //s[i]-s[0]就是s[i]
        int res=-0x3f3f3f3f;
        for(int i=1;i<=n;i++)
        {
            if(!q.isEmpty()&&i-q.peekFirst()>m) q.pollFirst(); //如果长度超过m则缩小滑窗
            res=Math.max(res,s[i]-s[q.peekFirst()]);
            while(!q.isEmpty()&&s[q.peekLast()]>=s[i]) q.pollLast(); //维护单调递增的队列
            q.offerLast(i);
        }
        wt.print(res);
        
        wt.flush();
    }
    
    static class rd
    {
        static BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));
        static StringTokenizer tk=new StringTokenizer("");
        
        static String nextLine() throws IOException
        {
            return bf.readLine();
        }
        
        static String next() throws IOException
        {
            while(!tk.hasMoreTokens()) tk=new StringTokenizer(bf.readLine());
            return tk.nextToken();
        }
        
        static int nextInt() throws IOException
        {
            return Integer.parseInt(next());
        }
        
        static double nextDouble() throws IOException
        {
            return Double.parseDouble(next());
        }
        
        static long nextLong() throws IOException
        {
            return Long.parseLong(next());
        }
        
        static BigInteger nextBig() throws IOException
        {
            BigInteger d=new BigInteger(rd.nextLine());
            return d;
        }
    }
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/376602.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Redis 主从库如何实现数据一致?

目录 1、主从库间如何进行第一次同步&#xff1f; 2、主从级联模式分担全量复制时的主库压力 3、主从库间网络断了怎么办&#xff1f; 总结 // 好的文章&#xff0c;值得反复去读 Redis 具有高可靠性&#xff0c;这里有两层含义&#xff1a;一是数据尽量少丢失&#xff0c;…

2023JAVA面试题全集超全面超系统超实用!早做准备早上岸

2022年我凭借一份《Java面试核心知识点》成功拿下了阿里、字节、小米等大厂的offer&#xff0c;两年的时间&#xff0c;为了完成我给自己立的flag&#xff08;拿下一线互联网企业offer大满贯&#xff09;&#xff0c;即使在职也一直在不断的学习与备战面试中&#xff01;——或…

【Spark分布式内存计算框架——Spark Streaming】6. DStream(下)流式应用状态 Kafka

3.3 流式应用状态 使用SparkStreaming处理实际实时应用业务时&#xff0c;针对不同业务需求&#xff0c;需要使用不同的函数。SparkStreaming流式计算框架&#xff0c;针对具体业务主要分为三类&#xff0c;使用不同函数进行处理&#xff1a; 业务一&#xff1a;无状态Statel…

【数电基础】——数制和码制

目录 1.概述 1.信号&#xff08;电路&#xff09;的功能 2.信号的分类&#xff1a; 3.数字信号的输入和输出的逻辑关系表示方法 2.数制 1.十进制&#xff08;D/d&#xff09; 2.二进制(B/b) 3.八进制&#xff08;O/o&#xff09; 4.十六进制&#xff08;H/h&#xff09;…

使用huggingface微调预训练模型

官方教程&#xff1a;https://huggingface.co/docs/transformers/training 准备数据集&#xff08;基于datasets库&#xff09; train.json 数据格式&#xff1a; {"source":"你是谁&#xff1f;", "target":"我是恁爹"} {"so…

FSP:Flow of Solution Procedure (CVPR 2017) 原理与代码解析

paper&#xff1a;A Gift From Knowledge Distillation: Fast Optimization, Network Minimization and Transfer Learningcode&#xff1a;https://github.com/HobbitLong/RepDistiller/blob/master/distiller_zoo/FSP.py背景深度神经网络DNN逐层生成特征。更高层的特征更接近…

内存数据库的设计与实现(已在大型项目中应用)

一、概况 1、设计总图 组成,由Redis集群缓存,普通缓存,传统数据库,各类数据驱动 2、内存数据库的增删改查,分页查询 组成,由数据查询,分页查询,数据存储,数据修改,数据删除 3、内存数据库的驱动 组成,由驱动适配器,普通缓存驱动,Redis缓存驱动 4、内存数据库与…

C++常见类型及占用内存表

GPS生产厂家在定义数据的时候都会有一定的数据类型&#xff0c;例如double、int、float等&#xff0c;我们知道它们在内存中都对应了一定的字节大小&#xff0c;而我在实际使用时涉及到了端序的问题&#xff08;大端序高字节在前&#xff0c;小端序低字节在前&#xff09;&…

redis主从同步:如何实现数据一致

Redis 提供了主从库模式&#xff0c;以保证数据副本的一致&#xff0c;主从库之间采用的是读写分离的方式。读操作&#xff1a;主库、从库都可以接收&#xff1b;写操作&#xff1a;首先到主库执行&#xff0c;然后&#xff0c;主库将写操作同步给从库。和mysql差不多。但是同步…

自动驾驶专题介绍 ———— 毫米波雷达

文章目录介绍工作原理特点性能参数应用厂家介绍 毫米波雷达是工作在毫米波波段探测的雷达&#xff0c;与普通雷达相似&#xff0c;是通过发射无线电信号并接收反射信号来测量物体间的距离。毫米波雷达工作频率为30~300GHz(波长为1 - 10mm)&#xff0c;波长介于厘米波和光波之间…

【数据挖掘实战】——家用电器用户行为分析及事件识别(BP神经网络)

项目地址&#xff1a;Datamining_project: 数据挖掘实战项目代码 目录 一、背景和挖掘目标 1、问题背景 2、原始数据 3、挖掘目标 二、分析方法与过程 1、初步分析 2、总体流程 第一步&#xff1a;数据抽取 第二步&#xff1a;探索分析 第三步&#xff1a;数据的预处…

为什么负责任的技术始于数据治理

每个组织都处理数据&#xff0c;但并非每个组织都将其数据用作业务资产。但是&#xff0c;随着数据继续呈指数级增长&#xff0c;将数据视为业务资产正在成为竞争优势。 埃森哲的一项研究发现&#xff0c;只有 33% 的公司“足够信任他们的数据&#xff0c;能够有效地使用它并从…

色环电阻的阻值如何识别

这种是色环电阻&#xff0c;其外表有一圈圈不同颜色的色环&#xff0c;现在在一些电器和电源电路中还有使用。下面的两种色环电阻它颜色还不一样&#xff0c;一个蓝色&#xff0c;一个土黄色&#xff0c;其实这个蓝色的属于金属膜色环电阻&#xff0c;外表涂的是一层金属膜&…

Qt新手入门指南 - 如何创建模型/视图(四)

每个UI开发人员都应该了解ModelView编程&#xff0c;本教程的目标是为大家提供一个简单易懂的介绍。Qt 是目前最先进、最完整的跨平台C开发工具。它不仅完全实现了一次编写&#xff0c;所有平台无差别运行&#xff0c;更提供了几乎所有开发过程中需要用到的工具。如今&#xff…

AJAX介绍及其应用

1.1 AJAX 简介 AJAX全称为 Asynchronous JavaScript and XML &#xff0c;就是异步的js和xml。通过AJAX可以在浏览器中向服务器发送异步请求&#xff0c;最大的优势&#xff0c;无刷新获取数据。AJAX不是新的编程语言&#xff0c;而是一种现有的标准组合再一起使用的新方式 应…

scanpy 单细胞分析API接口使用案例

参考&#xff1a;https://zhuanlan.zhihu.com/p/537206999 https://scanpy.readthedocs.io/en/stable/api.html scanpy python包主要分四个模块&#xff1a; 1&#xff09;read 读写模块、 https://scanpy.readthedocs.io/en/stable/api.html#reading 2&#xff09;pp Prepr…

springBoot自动装配原理探究springBoot配置类Thymeleaf模板引擎

微服务 微服务是一种架构风格&#xff0c;由于单体架构不利于团队协作完成并且代码量较大&#xff0c;后期维护成本较高&#xff0c;逐渐有了微服务架构。微服务是将一个项目拆分成不同的服务&#xff0c;各个服务之间相互独立互不影响&#xff0c;互相通过轻量级机制通信比如…

(转载)STM32与LAN9252构建EtherCAT从站

目录 &#xff08;一&#xff09;&#xff1a;项目简介 EtherCAT及项目简述 LAN9252工作模式 整体开发流程 移植要处理的问题 代码层面的工作 开发中使用的工具 &#xff08;二&#xff09;&#xff1a;SSC的使用 SSC简介和下载 SSC构建协议栈文件和XML &#xff08…

爬虫数据解析-正则表达式

数据解析-正则表达式 正则表达式 正则编写规则简介 字符含义.匹配除换行符以外的任意字符|A|B表示&#xff1a;匹配正则表达式条件A或B^匹配字符串的开始(在集合[]里表示"非"&#xff09;的意思$匹配字符串的结束{n}重复n次{,n}重复小于n次{n,}重复n次或更多次{n,…

2023软件测试金三银四常见的软件测试面试题-【抓包和网络协议篇】

八、抓包与网络协议 8.1 抓包工具怎么用 我原来的公司对于抓包这块&#xff0c;在App的测试用得比较多。我们会使用fiddler抓取数据检查结果&#xff0c;定位问题&#xff0c;测试安全&#xff0c;制造弱网环境; 如&#xff1a;抓取数据通过查看请求数据&#xff0c;请求行&…