每日算法 - 设计循环队列(基础算法)

2 队列 字节校园每日一题——第三周 力扣C++ Java 每日一题总结 第三周共6道队列、链表相关题 精选三道字节校园高频面试题!虽然是面向题解解题 但是还是很有收获!慢慢进步 慢慢掌握套路!冲!!! 阅读详情

目录

题目

解题思路

1、数组

数组实现代码

单链表代码(思路见链接)


题目

设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。

循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。

你的实现应该支持如下操作:

MyCircularQueue(k): 构造器,设置队列长度为 k 。
Front: 从队首获取元素。如果队列为空,返回 -1 。
Rear: 获取队尾元素。如果队列为空,返回 -1 。
enQueue(value): 向循环队列插入一个元素。如果成功插入则返回真。
deQueue(): 从循环队列中删除一个元素。如果成功删除则返回真。
isEmpty(): 检查循环队列是否为空。
isFull(): 检查循环队列是否已满。
 

示例:

MyCircularQueue circularQueue = new MyCircularQueue(3); // 设置长度为 3
circularQueue.enQueue(1);  // 返回 true
circularQueue.enQueue(2);  // 返回 true
circularQueue.enQueue(3);  // 返回 true
circularQueue.enQueue(4);  // 返回 false,队列已满
circularQueue.Rear();  // 返回 3
circularQueue.isFull();  // 返回 true
circularQueue.deQueue();  // 返回 true
circularQueue.enQueue(4);  // 返回 true
circularQueue.Rear();  // 返回 4
 

提示:

所有的值都在 0 至 1000 的范围内;
操作数将在 1 至 1000 的范围内;
请不要使用内置的队列库。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/design-circular-queue
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。


解题思路

https://leetcode-cn.com/problems/design-circular-queue/solution/she-ji-xun-huan-dui-lie-by-leetcode/

 

1、数组

思路

根据问题描述,该问题使用的数据结构应该是首尾相连的 环。

任何数据结构中都不存在环形结构,但是可以使用一维 数组 模拟,通过操作数组的索引构建一个 虚拟 的环。很多复杂数据结构都可以通过数组实现。

对于一个固定大小的数组,任何位置都可以是队首,只要知道队列长度,就可以根据下面公式计算出队尾位置:

想象一下将原数组从headIndex处增加队列长度,构成长度为headIndex + count  的数组,然后通过取余去掉原数组后面的数组。

tailIndex=(headIndex+count−1) mod capacity

其中 capacity 是数组长度,count 是队列长度,headIndex 和 tailIndex 分别是队首 head 和队尾 tail 索引。

下图展示了使用数组实现循环的队列的例子。

 

queue:一个固定大小的数组,用于保存循环队列的元素。

headIndex:一个整数,保存队首 head 的索引。

count:循环队列当前的长度,即循环队列中的元素数量。使用 hadIndex 和 count 可以计算出队尾元素的索引,因此不需要队尾属性。

capacity:循环队列的容量,即队列中最多可以容纳的元素数量。该属性不是必需的,因为队列容量可以通过数组属性得到,但是由于该属性经常使用,所以我们选择保留它。这样可以不用在 Python 中每次调用 len(queue) 中获取容量。但是在 Java 中通过 queue.length 获取容量更加高效。为了保持一致性,在两种方案中都保留该属性。


数组实现代码

/**
 * 循环队列,环形缓冲器
 */

public class MyCircularQueue {
    private int[] queue;// 数组
    private int headIndex;// 队列
    private int capacity;// 队列总容量
    private int count;// 队列当前长度

    /**
     * 初始化
     */
    public MyCircularQueue(int k) {
        this.capacity = k;
        this.queue = new int[k];
        this.headIndex = 0;
        this.count = 0;
    }

    /**
     * 插入元素
     */
    public boolean enQueue(int value) {
        if (this.count == capacity)
            // 队列满
            return false;
        this.queue[(this.headIndex + this.count) % this.capacity] = value;
        this.count += 1;
        return true;
    }

    /**
     * 删除元素
     */
    public boolean deQueue(int value) {
        if (this.count == 0)
            // 队列空
            return false;
        this.headIndex = (this.headIndex + 1) % capacity;
        this.count -= 1;
        return true;
    }

    /**
     * 获取队首
     */
    public int Front(){
        if (this.count == 0)
            return -1;
        return this.queue[this.headIndex];
    }

    /**
     * 获取队尾
     */
    public int Rear(){
        if (this.count == 0)
            return -1;
        int tailIndex = (this.headIndex + this.count - 1 ) % this.capacity;
        return this.queue[tailIndex];
    }

    /**
     * 检查循环队列是否为空
     */
    public boolean isEmpty(){
        return (this.count == 0);
    }

    /**
     * 检查队列是否满
     */
    public boolean isFull(){
        return (this.count == this.capacity);
    }
}

 


单链表代码(思路见链接)

 

class Node {
  public int value;
  public Node nextNode;

  public Node(int value) {
    this.value = value;
    this.nextNode = null;
  }
}

class MyCircularQueue {

  private Node head, tail;
  private int count;
  private int capacity;

  /** Initialize your data structure here. Set the size of the queue to be k. */
  public MyCircularQueue(int k) {
    this.capacity = k;
  }

  /** Insert an element into the circular queue. Return true if the operation is successful. */
  public boolean enQueue(int value) {
    if (this.count == this.capacity)
      return false;

    Node newNode = new Node(value);
    if (this.count == 0) {
      head = tail = newNode;
    } else {
      tail.nextNode = newNode;
      tail = newNode;
    }
    this.count += 1;
    return true;
  }

  /** Delete an element from the circular queue. Return true if the operation is successful. */
  public boolean deQueue() {
    if (this.count == 0)
      return false;
    this.head = this.head.nextNode;
    this.count -= 1;
    return true;
  }

  /** Get the front item from the queue. */
  public int Front() {
    if (this.count == 0)
      return -1;
    else
      return this.head.value;
  }

  /** Get the last item from the queue. */
  public int Rear() {
    if (this.count == 0)
      return -1;
    else
      return this.tail.value;
  }

  /** Checks whether the circular queue is empty or not. */
  public boolean isEmpty() {
    return (this.count == 0);
  }

  /** Checks whether the circular queue is full or not. */
  public boolean isFull() {
    return (this.count == this.capacity);
  }
}

对插入元素加锁:

class MyCircularQueue {

  private Node head, tail;
  private int count;
  private int capacity;
  // Additional variable to secure the access of our queue
  private ReentrantLock queueLock = new ReentrantLock();

  /** Initialize your data structure here. Set the size of the queue to be k. */
  public MyCircularQueue(int k) {
    this.capacity = k;
  }

  /** Insert an element into the circular queue. Return true if the operation is successful. */
  public boolean enQueue(int value) {
    // ensure the exclusive access for the following block.
    queueLock.lock();
    try {
      if (this.count == this.capacity)
        return false;

      Node newNode = new Node(value);
      if (this.count == 0) {
        head = tail = newNode;
      } else {
        tail.nextNode = newNode;
        tail = newNode;
      }
      this.count += 1;

    } finally {
      queueLock.unlock();
    }
    return true;
  }
}
GEE:连续变化检测 CCD 第一步(导出ee.Algorithms.TemporalSegmentation.Ccdc函数的结果) 连续变化检测与分类(Continuous Change Detection and Classification, CCDC)主要有两个组件,一个连续变化检测 CCD,另外一个分类。在 Google Earth Engine (GEE)平台上进行 CCD 时间序列变化检测的时候,为了防止内存超限问题,将代码分为2阶段执行。第一阶段是运行 `ee.Algorithms.TemporalSegmentation.Ccdc` 函数,本文将详细介绍 CCD 的第一阶段的代码。 阅读详情

相关推荐

HAL库硬件SPI驱动ST7735 TFT屏幕:从零实现高效刷屏与图形绘制

本文详细介绍了如何使用STM32的HAL库硬件SPI驱动ST7735 TFT屏幕,从硬件连接到SPI配置优化,再到图形绘制与文本显示的实现。重点分享了DMA传输、局部刷新等高级优化技巧,显著提升刷屏效率,帮助开发者快速掌握屏幕驱动技术并应用于实际项目。

pink的博客 741

7.队列算法

队列是一种抽象的数据结构,有点类似于Stacks。与堆栈不同,队列的两端都是开放的。一端始终用于插入数据(入队),另一端用于删除数据(出队)。队列遵循先进先出方法,即首先访问先存储的数据项。一个真实的队列示例可以是单车道单向道路,车辆首先进入,首先退出。更多真实世界的例子可以看作是售票窗口和公共汽车站的队列。

感谢关注-最近在编写开源的自动化测试框架还没整理完 1574

LM358实战:手把手教你搭建电流检测电路(附电阻选型计算)

本文详细解析了使用LM358运算放大器搭建电流检测电路的全过程,包括基础原理、采样电阻选型、放大电路设计及PCB布局技巧。通过实战案例和精确计算,帮助工程师快速掌握低成本、高精度的电流检测方案,适用于电源管理、电机控制等多种应用场景。

weixin_30872157的博客 449

问题 H: 循环队列的实现

循环队列

weixin_74280897的博客 654

告别命令行!用这个开源的Web版Kettle工具,5分钟搞定数据集成任务编排

本文介绍了一款开源的Web版Kettle工具,通过直观的拖拽界面大幅提升数据集成效率,告别复杂的命令行操作。该工具基于Kettle核心引擎,支持跨平台协作、轻量化访问和降低学习曲线,特别适合业务分析师快速上手。实测显示,使用该工具后任务配置错误率下降62%,协作效率提升40%。

weixin_30267785的博客 435

ABAP ALV编辑后触发事件

1.FUNCTION ALV在it_events的参数中,写入对应的事件。2.OO ALV和FUNCTION ALV都可以,注册当前ALV的事件,对应的事件需要创建对象去实现。下面代码中,实现的是第一种,在it_events中写入事件。下面的代码是通过创建对象去实现ALV事件。

a86632678的博客 3852

【数据结构】队列的实现及应用和循环队列的实现【完整版】

讲解队列的概念和实现,队列的应用、队列的几道经典编程题,队列的概念选择题【完整版】

m0_74044018的博客 2285

【技术拆解】Illumina边合成边测序(SBS)核心流程全解析 | 从文库构建到数据分析

本文深入解析了Illumina边合成边测序(SBS)技术的完整流程。从DNA样本的文库构建(片段化、加接头、扩增),到Flowcell上的簇生成(桥式PCR),再到核心的边合成边测序(SBS)循环(荧光标记、可逆终止),最后简述了从原始数据到生物学洞见的数据分析步骤,为理解这一主流高通量测序技术提供了清晰的框架。

weixin_29201859的博客 536

队列-循环队列

数据结构-循环队列的基本实现 为了解决队列满,rear不能等于front的情况,这里使用flag标记上一次操作是入队还是出队。 个人思路:判断rear上一个数据结点是否为空&rear==front来区分队列空还是满,但是循环队列只是在逻辑上实现队列,数组数据存在残留,实现麻烦,就不做了 InitSqQueue(SqQueue& Q) Empty(SqQueue Q) EnQueue(SqQueue &Q) DeQueue(SqQueue& Q) GetHead(SqQ

子滨的博客 415

GaN制备micro-led(一)

随着第三代半导体 GaN 材料的快速发展,GaN 基 LED 发展迅速并广泛商业化,这 为可见光通信的实现及应用提供了基础。然而,普通商用 LED 的调制带宽只有几十兆 赫兹,并不能很好的满足可见光通信系统高传播速率的需求。为增大调制带宽,针对发 射端 LED 光源部分的改进仍需提高。将光子晶体结构引入 LED 芯片量子阱内部,能够 影响光子寿命和光子传播,进而改变 LED 芯片的调制带宽和光提取效率。结合倒装微 尺寸(Micro)LED 结构,使其封装体积最小化,这使得可见光通信能够更加灵活地.

weixin_45852211的博客 896

simulink的电动汽车制动系统热管理仿真

本文系统研究了电动汽车制动系统热管理仿真技术。通过建立机电液多物理场耦合模型,分析了不同工况下的动态热平衡特性。提出基于MPC的动态调节和NSGA-II多目标优化算法,使电池温度波动降低60%。创新性采用石墨烯相变材料与微通道液冷复合技术,冷却系统能耗减少40%。研究构建了完整的工程验证平台,涵盖200kW电制动测试台和高精度热成像系统。展望指出,未来将结合Transformer预测和强化学习算法,进一步优化热管理策略。该研究为电动汽车制动系统热管理提供了从理论建模到工程实施的完整解决方案。

xiaoheshang_123的博客 122

数据结构和算法--队列

## 如何理解队列 我们可以把它想成买票,先来的先买,后来的排到队尾,不允许插队,**先进者先出,这是典型的队列** 队列只包含来个操作,**入队enqueue()**,放一个数据到队列尾部,**出队dequeue()**,从队列头部取一个元素

R.先森的博客 347

AI快速变现之路,AI视频创作

初期投入$3000(工具订阅+样片制作),重点攻克跨境电商和本地生活服务市场。关注2025年AIGC视频工具的API降价趋势(如Pika企业版折扣可达50%),建议与云服务商签订长期合作协议。

qq_29896351的博客 1981

每日算法题【栈和队列】:栈和队列的实现、有效的括号、设计循环队列

在循环队列中,我们使用取模运算(%)来实现队列指针的循环移动。具体来说,当队尾指针需要向后移动时,我们计算新的队尾位置为 (tail + 1) % capacity,其中 tail 是当前队尾指针的位置,capacity 是队列的容量。这样可以保证当队尾指针达到队列容量时,取模运算会使其重新回到队列的开头,实现了环形结构。在普通的线性队列中,队列指针(如队头指针和队尾指针)的范围是从 0 到队列容量减一。而在循环队列中,队尾指针在达到队列容量时不再继续增加,而是从队列的开头重新开始,形成了一个环形结构。

m0_74951730的博客 540

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

Leetcode算法题

队列 & 栈 1. 岛屿数量 思路:循环遍历所有坐标。如果坐标值为1,将坐标值置为0,岛屿数量+1。同时将此坐标上下左右四个坐标加入队列,循环置0。 2. 打开转盘锁 思路:八叉树。

博客 249

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

LeetCode每日精进:622.设计循环队列

以队列长度k为4示例: 以队列长度k为4示例: 若用链表实现,那么就得使用环形链表实现循环结构 若用数组实现 分析:这样对比来看,用数组实现循环队列只需定义一个结构体,更加便捷。 以循环队列长度为4示例: 当循环队列长度为k时,我们申请k+1个数据空间的数组: 当队列为空,队头front和队尾rear指向同一个位置,即满足: 当队列已满时,rear的下一个位置指向front,即满足:

ll778811的博客 1116

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

【每日OJ —— 622. 设计循环队列】

每日OJ —— 622. 设计循环队列

qq_73900397的博客 530

『牛客|每日一题』循环队列

请你实现一个循环队列,该循环队列可利用的空间大小等于nn个int型变量的大小。 操作: push x:将xx加入到循环队列尾端。若循环队列已满,输出"full"(不含引号),否则不输出任何内容。保证xx为int型整数。 front:输出队首元素,队首不出队。若队列为空,输出"empty"(不含引号)。 pop:输出队首元素,且队首出队。若队列为空,输出"empty"(不含引号)。 输入描述: 第一行输入两个整数n,qn,q (1\le n,q \le 10^51≤n,q≤10 5 ),表示循环队列可利用

一个专注于客户端开发的技术er,不定期更新Android,Flutter,HormonyOS等方向的使用心得和感悟 877

#每日一题 设计循环队列

力扣https://leetcode-cn.com/problems/design-circular-queue/ 审题: 1.先进先出:模拟队列 2.通过头尾循环利用空间 :双向(头尾连接),题意已经暗示你用数组去模拟。 3.操作:功能函数 4.示例,便于我们写对返回值和传参 伪代码: 1.创建一个结构体,里面有指针a,有下标rear和front,(相当于头尾指针)还有k(存装有效数据的个数) 2.伪代码: MyCircularQueue*myCircularQueueC...

qq_54831038的博客 815

[Leetcode 每日精选](本周主题-设计) 622. 设计循环队列

题目难度: 中等 原题链接 今天我们来做一道 FIFO 的设计, 这下连带前两天的 LRU 和 LFU, 把常用的内存淘汰算法补齐了 ???? 大家有什么想法建议和反馈的话欢迎随时交流, 包括但不限于公众号聊天框/知乎私信评论等等~ 题目描述 设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。 循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就

随便发挥的博客 241

『牛客 每日一题』循环队列_已知一个顺序循环队列最多能容纳60个元素,当front=47,rear=23时,该队列有多少

值得注意的细节是,对(n+1)取余,而不是对n取余。可以这么理解要判断队列满了,(img-TbUjnNXi-1713336946940)],这也是为什么代码中开辟的队列空间大小为(n+1)而不是n的缘由。对于循环队列我们要考虑的问题主要是,对于可存n个整型数据的队列。888 (备注大数据)**

2301_77054033的博客 679

每日算法-250403

核心思路是滑动窗口,目标是找到一个最短的子串,替换掉这个子串后,原字符串中剩余部分的 Q, W, E, R 字符数量都不超过。这次复习时遇到了一个小问题:忘记处理输入字符串本身就已经平衡的情况(即每个字符出现次数都等于。如果一开始就平衡,应该直接返回 0。不处理这个边界情况,会导致后续滑动窗口的。个 ‘1’ 的子串,然后在这些子串中比较长度和字典序。我们可以使用滑动窗口来解决这个问题。,使得窗口长度为 0,不会错误地增加计数。,使得窗口外的字符计数满足平衡条件。,并记录窗口内元素的乘积。

2403_83543687的博客 965

【每日算法】AB8 循环队列(基于数组)

牛客AB8 循环队列

weixin_50497501的博客 310

【数据结构与算法】栈和队列的综合应用:1.用栈实现队列 2.用队列实现栈 3.设计循环队列

本文介绍了栈和队列的相互实现方法及循环队列的设计原理。通过双栈模拟队列实现"先进先出"特性,利用双队列保持一个队列为空的方式实现栈的"后进先出"特性。文中提供了完整的C语言实现代码,包括栈/队列的基本操作函数,以及两种数据结构相互转换的核心算法。最后还讲解了循环队列的环形缓冲区实现方式,通过维护头尾指针和判空/满标志来优化空间利用率。这些经典问题考察了对线性表特性的深入理解和灵活运用能力,是数据结构学习的重要实践案例。

小龙报的博客 638

力扣每日一题NO.622——循环队列

题目描述 设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。 循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。 你的实现应该支持如下操作: MyCircularQueue(k): 构造器,设置队列长度为 k 。 Front: 从队首获取元素。如果队列

dtxew love c++ 385

2-3 LC622 设计循环队列 字节校园每日一题 LC449 序列化和反序列化二叉搜索树 Java力扣刷题笔记

LC622 开始有队列的题了鸭!

一碗菜粥的博客 578
上一篇: 每日算法 - 二叉树中序遍历(基础算法)
下一篇: 每日算法 - 无重复字符的最长子串
Longtermevolution
博客等级 码龄9年 113粉丝 249原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值