队列(Queue),循环队列,双端队列(Deque)and LeetCode刷题

队列(Queue),循环队列,双端队列(Deque)and LeetCode刷题

  • 1. 队列的概念
  • 2.队列的使用
  • 3. 队列的模拟实现
    • 3.1 用链式结构实现队列
    • 3.2 用顺序结构实现队列
  • 4. 循环队列
  • 5. 双端队列(Deque)
  • 6. LeetCode刷题
    • 6.1 用队列实现栈
    • 6.2 用栈实现队列

1. 队列的概念

什么是队列?打个比方,就是一群人在排队买东西,先排队的人先拿到东西先离开,后排队的人后拿到东西后离开。

因此,队列是一种 只允许在一端进行插入数据操作,在另一端进行删除数据操作 的特殊线性表,即 “先进先出” ,而栈是“先进后出”。其中,进行插入操作的一端称为队尾(Tail/Rear),该操作叫做入队; 进行删除操作的一端称为队头(Head/Front),该操作叫做出队。在使用队列时,可以画出这样的图形

在这里插入图片描述

2.队列的使用

Queue是一个 接口 ,底层是 由LinkedList实现 的!

Queue里的方法是比较少的,如图:
在这里插入图片描述
其中,红色框框里的是一组,橙色框框里的是一组;两组的方法都差不多,一般情况下用的是红色框框里的方法

  • offer(E):boolean 入列
  • poll():E 出列
  • peek():E获取队头元素

另外,Queue继承于Collection接口里的两个方法也比较常用:

  • size():int 获取队列元素个数
  • isEmpty():boolean 判断队列是否为空

在这里插入图片描述

public class Test {public static void main(String[] args) {Queue<Integer> queue = new LinkedList<>();queue.offer(1);queue.offer(2);queue.offer(3);queue.offer(4);queue.offer(5);System.out.println(queue.poll());//1System.out.println(queue.size());//4System.out.println(queue.peek());//2System.out.println(queue.isEmpty());//false}
}

注意: Queue是接口,不能进行实例化接口,而是实例化LinkedList对象,因为LinkedList实现了Queue接口!

3. 队列的模拟实现

常见的结构有顺序结构链式结构,那么我们模拟实现队列时,选用什么结构来实现呢?答案是都是可以的!

3.1 用链式结构实现队列

链式结构包括单链表和双链表,两种都是可以用来实现的

  • 假如用单链表来实现,为了使时间复杂度更小,必须要采用头删和尾插,并且需要一个tail引用来标记尾节点,当然也需要head来标记头节点
  • 假如用双链表来实现的话,那就灵活多了,既可以用头删和尾插来模拟实现出队和入队,也可以使用尾删和头插!

下面仅用双链表来模拟实现

public class MyQueue {static class ListNode {public int val;public ListNode prev;public ListNode next;public ListNode(int val) {this.val = val;}}public ListNode first = null;public ListNode last = null;public int usedSize = 0;public void offer(int val) {ListNode node = new ListNode(val);if(first == null) {first = last = node;}else {node.prev = last;last.next = node;last = node;}usedSize++;}public int poll() {if(first == null) {return -1;} else {int ret = first.val;first = first.next;if(first != null){first.prev = null;}usedSize--;return ret;}}public int peek() {if(first == null) {return -1;} else {return first.val;}}public boolean isEmpty() {return usedSize == 0;}
}

3.2 用顺序结构实现队列

如果使用数组去实现队列,当出队列后,要么把所有的元素都往前挪一位,然而这很浪费时间;要么就要浪费空间,当有大量的出队操作时,就会浪费大量的空间,简直是得不偿失!

那有什么办法可以解决这些问题呢?我们假如可以把数组的首尾连起来,构成循环,出队操作可以直接将队头往后挪一个位置,而原来的位置又能被后面的入队元素占据,这样既能节省时间,又不会浪费空间,接下来就来学习一下循环队列

4. 循环队列

环形队列通常使用数组实现

如图,在一个长度为8的循环队列中,存放12、23、34、45、56元素,用front标记队头,用rear标记队尾,注意rear是数组中最后一个有效元素的下一个

在这里插入图片描述
内圈表示数组的下标,外圈表示数组存放的元素。构建好基本的框架后,问题来了

问题1: 如何判空和判满

判空:只要front和rear相遇,就是空
判满:

  • 方式1:定义一个变量usedSize,表示当前数组中存放有效数据的个数
  • 方式2:添加标记,定义一个boolean类型的标记
  • 方式3:浪费一个空间,每次添加元素时判断rear的下一个是不是front,若是则已满

在这里插入图片描述
如图,利用方式3,则该循环队列已满,因为rear的下一位是front。该方式浪费了一个空间

问题2: rear或front下标如何由7位置到0位置?可以利用如下公式:(rear + 1) % arr.length

废话不多说,直接上链接来用顺序结构来实现队列,题目链接:622. 设计循环队列

采用方式1的代码如下:

class MyCircularQueue {public int[] elem;public int front;public int rear;public int usedSize;public MyCircularQueue(int k) {elem = new int[k];}public boolean enQueue(int value) {if(isFull()) {return false;}elem[rear] = value;rear = (rear+1) % elem.length;usedSize++;return true;}public boolean deQueue() {if(isEmpty()) {return false;}front = (front+1) % elem.length;usedSize--;return true;}public int Front() {if(isEmpty()) {return -1;}return elem[front];}public int Rear() {if(isEmpty()) {return -1;}int index = rear == 0? elem.length-1 : rear-1;return elem[index];}public boolean isEmpty() {if(usedSize == 0) {return true;}return false;}public boolean isFull() {if(usedSize == elem.length) {return true;}return false;}
}

5. 双端队列(Deque)

双端队列(deque)是指允许两端都可以进行入队和出队操作的队列,deque 是 “double ended queue” 的简称。那就说明元素可以从队头出队和入队,也可以从队尾出队和入队。这也就说明,无论是栈,还是队列,都可以使用该接口

同样地,Deque是一个接口,使用时必须创建LinkedList的对象。

在实际工程中,使用Deque接口是比较多的,栈和队列均可以使用该接口

    Deque<Integer> stack = new ArrayDeque<>();//双端队列的线型实现Deque<Integer> queue = new LinkedList<>();//双端队列的链式实现

6. LeetCode刷题

6.1 用队列实现栈

题目链接:225. 用队列实现栈

解题思路:

  1. 创建两个队列,当进行模拟栈的pop操作时,元素会从其中的一个队列转移到另外一个队列,两个队列交替来存放所有元素
  2. 没有进行操作时,如果要实现的栈不为空,始终只有一个队列存有元素,另外一个队列为空
  3. push操作:将元素放入非空队列中,若都是空对列则放入第一个队列中
  4. pop操作:将非空队列中的元素依次放入另外一个队列中,只有最后一个元素出队
  5. top操作与pop操作大同小异

代码如下:

class MyStack {public Queue<Integer> q1;public Queue<Integer> q2;public MyStack() {q1 = new LinkedList<>();q2 = new LinkedList<>();}public void push(int x) {if(!q1.isEmpty()) {q1.offer(x);}else if(!q2.isEmpty()) {q2.offer(x);}else {q1.offer(x);}}public int pop() {if(empty()) {return -1;}if(!q1.isEmpty()) {int size = q1.size();for(int i = 0; i < size-1; i++) {q2.offer(q1.poll());}return q1.poll();}else {int size = q2.size();for(int i = 0; i < size-1; i++) {q1.offer(q2.poll());}return q2.poll();}}public int top() {if(empty()) {return -1;}if(!q1.isEmpty()) {int size = q1.size();for(int i = 0; i < size-1; i++) {q2.offer(q1.poll());}int val = q1.peek();q2.offer(q1.poll());return val;}else {int size = q2.size();for(int i = 0; i < size-1; i++) {q1.offer(q2.poll());}int val = q2.peek();q1.offer(q2.poll());return val;}}public boolean empty() {return q1.isEmpty() && q2.isEmpty();}
}

6.2 用栈实现队列

题目链接:232. 用栈实现队列

解题思路:

  1. 创建两个栈,其中一个栈s1专门用来入队,另外一个栈专门用来出队
  2. 入队时,将元素添加进栈s1中
  3. 出队时,判断栈s2是否为空,若为空则将s1中的全部元素依次都添入s2中,再将s2中的栈顶元素弹出;若s2不为空则直接将s2中的栈顶元素直接弹出

代码如下:

class MyQueue {public Stack<Integer> s1;public Stack<Integer> s2;public MyQueue() {s1 = new Stack<>();s2 = new Stack<>();}public void push(int x) {s1.push(x);}public int pop() {if(s2.isEmpty()) {while(!s1.isEmpty()) {s2.push(s1.pop());}}return s2.pop();}public int peek() {if(s2.isEmpty()) {while(!s1.isEmpty()) {s2.push(s1.pop());}}return s2.peek();}public boolean empty() {return s1.isEmpty() && s2.isEmpty();}
}

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

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

相关文章

【内网安全】横向移动-Wmi-Smb-CME密码喷射

目录 环境介绍域信息收集-横向移动前置判断是不是在域内获取域控主机的内网ip端口扫描内网获取主机密码 域横向移动-WMI-自带&命令&套件&插件1.wmic系统自带&#xff1a;(单执行&#xff1a;即无回显) 2.cscript系统自带&#xff1a;(交互式) 3.wmiexec-impacket&a…

文献阅读:A Case for Managed and Model-less Inference Serving

目录 知识点记录推理服务在线推理特点 动机&#xff1a;为什么作者想要解决这个问题&#xff1f;贡献&#xff1a;作者在这篇论文中完成了什么工作(创新点)&#xff1f;规划&#xff1a;他们如何完成工作&#xff1f;1.挑战1.1 选择一个模型变体1.2 异构硬件1.3 资源提供1.4 启…

MySQL双主双从实现方式

双主双从&#xff08;MM-SS&#xff09; 前言 避免单一主服务器宕机&#xff0c;集群写入能力缺失 从 1 复制 主1 &#xff0c;从 2 复制 主 2 主 1 复制 主 2&#xff0c;主 2 复制主 1 也就是 主 1 和主 2 互为主从。主1主2互为主从&#xff0c; 是为了以下情景&#xff0c…

初识XXE漏洞及ctfshow做题(373-378)

初识XXE漏洞 1.XXE简介 XXE就是XML外部实体注入&#xff0c;当允许引用外部实体时&#xff0c; XML数据在传输中有可能会被不法分子被修改&#xff0c;如果服务器执行被恶意插入的代码&#xff0c;就可以实现攻击的目的攻击者可以通过构造恶意内容&#xff0c;就可能导致任意…

昇思25天学习打卡营第29天 | 文本解码原理--以MindNLP为例

今天是29天&#xff0c;学习了文本解码原理--以MindNLP为例。 MindNLP 是一个基于 MindSpore 的开源自然语言处理&#xff08;NLP&#xff09;库。它具有以下特点&#xff1a; 支持多种 NLP 任务&#xff1a;如语言模型、机器翻译、问答、情感分析、序列标记、摘要等&#xff…

SPINDILOMETER:用于多导睡眠图的睡眠纺锤波模型

摘要 通过对近年来睡眠脑电(EEG)信号分析方法的研究&#xff0c;本文提出了一种可集成到多导睡眠图(PSG)设备中的SPINDILOMETER模型&#xff0c;以供PSG电生理信号研究人员、临床睡眠医生和技术人员使用。为此&#xff0c;通过分析PSG中的脑电信号&#xff0c;开发了一个测量睡…

算法题目整合

文章目录 121. 小红的区间翻转142. 两个字符串的最小 ASCII 删除总和143. 最长同值路径139.完美数140. 可爱串141. 好二叉树 121. 小红的区间翻转 小红拿到了两个长度为 n 的数组 a 和 b&#xff0c;她仅可以执行一次以下翻转操作&#xff1a;选择a数组中的一个区间[i, j]&…

【Neural signal processing and analysis zero to hero】- 2

Nonstationarities and effects of the FT course from youtube: 传送地址 why we need extinguish stationary and non-stationary signal, because most of neural signal is non-stationary. Welch’s method for smooth spectral decomposition Full FFT method y…

用Docker来开发

未完成。。。 现在好像用Docker是越来越多了。之前其实也看过docker的原理&#xff0c;大概就是cgroup那些&#xff0c;不过现在就不看原理了&#xff0c;不谈理论&#xff0c;只看实际中怎么用&#xff0c;解决眼前问题。 用docker来做开发&#xff0c;其实就是解决的编译环境…

ArkUI-动画

属性动画 属性动画是通过设置组建的animation属性来给组件添加动画&#xff0c;当组件的width、height、Opacity、backgroundColor、scale、rotate、translate等属性变更时&#xff0c;可以实现渐变过渡效果 Text().position({x: 10, //x轴坐标y: 0 //y轴坐标}).rotate…

在 PostgreSQL 里如何处理数据的存储优化和查询优化的优先级权衡?

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01;&#x1f4da;领书&#xff1a;PostgreSQL 入门到精通.pdf 文章目录 在 PostgreSQL 里如何处理数据的存储优化和查询优化的优先级权衡一、存储优化与查询优化的概述&#x…

阿里:深入探讨Java的分层编译

本文主要探讨Java虚拟机&#xff08;JVM&#xff09;中的分层编译&#xff08;Tiered Compilation&#xff09;机制及其对程序性能的影响。 前言 一开始接触到分层编译是因为我们这的服务每次发布/重启后都会短暂地出现CPU满线程池满的情况&#xff0c;然后过一段时间又能自动…

学习008-01-03 Customize the Application UI and Behavior(自定义应用程序UI和行为)

Customize the Application UI and Behavior&#xff08;自定义应用程序UI和行为&#xff09; In XAF, the data model defines the database structure and UI. Changes to your entity classes affect the UI. For example, if you add a new property to an entity class, …

C++ | Leetcode C++题解之第239题滑动窗口最大值

题目&#xff1a; 题解&#xff1a; class Solution { public:vector<int> maxSlidingWindow(vector<int>& nums, int k) {int n nums.size();vector<int> prefixMax(n), suffixMax(n);for (int i 0; i < n; i) {if (i % k 0) {prefixMax[i] num…

MySQL(7)内外连接+索引

目录 1.内外连接; 2. 索引; 1.内外连接: 1.1内连接: 语法: select 字段 from 表名 inner join 表名 on 字段限制; 1.2 外连接: 分为左右外连接; (1)左外连接: 语法: select * from 表名 left join 表名 on 字段限制. &#x1f330;查询所有学生的成绩&#xff0c;如果这个学生…

MySQL(8)事务

目录 1.事务; 1.事务: 1.1 如果CURD不加限制会这么样子? 可能造成数据同时被修改, 数据修改的结果是未知的.(可以想一下之前的抢票线程问题) 1.2 事务概念: 事务就是一组DML语句组成&#xff0c;这些语句在逻辑上存在相关性&#xff0c;这一组DML语句要么全部成功&#xff0…

【Python实战因果推断】40_双重差分11

目录 Heterogeneous Effect over Time Heterogeneous Effect over Time 有好消息也有坏消息。首先是好消息&#xff1a;你已经发现了问题所在。也就是说&#xff0c;你知道 TWFE 在应用于具有时间异构效应的交错采用数据时是有偏差的。用更专业的术语来说&#xff0c;您的数据…

TDesign组件库日常应用的一些注意事项

【前言】Element&#xff08;饿了么开源组件库&#xff09;在国内使用的普及率和覆盖率高于TDesign-vue&#xff08;腾讯开源组件库&#xff09;&#xff0c;这也导致日常开发遇到组件使用上的疑惑时&#xff0c;网上几乎搜索不到其文章解决方案&#xff0c;只能深挖官方文档或…

大厂面试官问我:Redis为什么使用哈希槽的方式进行数据分片?为什么不适用一致性哈希的方式?【后端八股文十三:Redis 集群哈希八股文合集(1)】

本文为【Redis 集群哈希 八股文合集&#xff08;1&#xff09;】初版&#xff0c;后续还会进行优化更新&#xff0c;欢迎大家关注交流~ hello hello~ &#xff0c;这里是绝命Coding——老白~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注…

pdf怎么转换成图片?3种PDF转图片方法分享

pdf怎么转换成图片&#xff1f;将PDF转换成图片不仅满足了快速分享的需求&#xff0c;还便于在多种平台上展示。特别是在社交媒体、演示文稿或在线文档中&#xff0c;图片格式的PDF页面更加直观易用。此外&#xff0c;转换成图片后&#xff0c;我们还可以利用图片编辑工具对PDF…