当前位置: 首页 > news >正文

L33.【LeetCode笔记】循环队列(数组解法)

目录

1.题目

2.分析

方法1:链表

尝试使用单向循环链表模拟

插入节点

解决方法1:开辟(k+1)个节点

解决方法2:使用变量size记录队列元素个数

获取队尾元素

其他函数的实现说明

方法2:数组

重要点:指针越界的解决方法

方法1:单独判断

方法2:取模

3.数组代码的逐步实现

方法1:越界时单独判断

提交结果

方法2:每次都取模

提交结果


1.题目

https://leetcode.cn/problems/design-circular-queue/

设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 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 的范围内;
  • 请不要使用内置的队列库。

2.分析

方法1:链表

看到本题,很容易想到用链表解

尝试使用单向循环链表模拟

例如k==3,很容易想到开辟三个空节点

要访问循环队列的头和尾,需要两个指针front(头指针)和rear(尾指针),初始状态下,链表为空时,front和rear都指向同一个节点

现检测链表的功能是否能正常执行

插入节点

每插入一个元素,按队列"先进先出"原则,应该rear++,如下图:

当队列满时,如下图:

发现问题:队列为空或满时,front和rear都指向同一个节点,无法区分

解决方法1:开辟(k+1)个节点

增加一个节点后,当队列满时,rear->next==front;当队列为空时,rear==front

解决方法2:使用变量size记录队列元素个数

当队列为空时,size==0;当队列满时,size==k.以此来区分两种情况

获取队尾元素

无论开辟(k+1)个节点还是使用变量size记录队列元素个数,rear都指向尾节点的下一个节点,需要找尾(时间复杂度为,较消耗时间),或者另外使用一个rear_prev变量来记录rear指向节点的前一个节点,或者使用双向链表

其他函数的实现说明

从队首获取元素:返回front指向的节点的值即可

删除一个元素:front++

方法2:数组

讲讲和链表的不同点:

重要点:指针越界的解决方法

1.无论开辟(k+1)个节点还是使用变量size记录队列元素个数,front和rear都有越界的可能性

以开辟(k+1)个节点举例:

例如下图,再插入一个元素,如果rear++,则会越界

例如下图,再删除一个元素,如果front++,则会越界

 2.获取队尾元素时,可能出现rear越界访问的情况

当队列不为空时,直接访问return obj->arr[obj->rear-1];可能访问到obj->arr[-1]的位置,可以单独判断或者对rear取模

方法1:单独判断

如果rear+1越界,则rear=0;如果front+1越界,则front=0;

方法2:取模

队列未满时,插入元素:当rear==k时,再插入元素时rear++,之后处理越界的rear,使其等于0,则,rear==(rear+1)%(k+1)

队列不为空时,删除元素:当front==k时,再插入元素时front++,之后处理越界的front,使其等于0,则,front==(front+1)%(k+1)

队列不为空时,访问队尾元素:例如rear==0,要访问到rear==k的位置,即arr[(rear-1+k+1)%(k+1)==arr[(rear+k)%(k+1)

判断队列是否已满,如果满了,例如rear==k,要使rear的下一个为front==0,即判断(rear+1)%(k+1)==front

3.数组代码的逐步实现

读题可知:如果用数组来模拟循环队列,那么结构体成员变量应该有4个

1.指向数组的指针a,类型为int*

2.队首和队尾各需要一个变量来访问:front和rear,类型都为int,充当数组a的下标

3.队列的长度k,类型为int

显然应该用malloc在堆区上开辟空间,接收的指针为结构体指针,否则函数返回后,栈区空间会被销毁

之后初始化结构体的成员变量

方法1:越界时单独判断

typedef struct 
{int* arr;int front;int rear;int k;
} MyCircularQueue;MyCircularQueue* myCircularQueueCreate(int k) 
{MyCircularQueue* obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));obj->arr=(int*)malloc(sizeof(int)*(k+1));obj->front=obj->rear=0;obj->k=k;return obj;
}bool myCircularQueueIsFull(MyCircularQueue* obj);//先声明
bool myCircularQueueIsEmpty(MyCircularQueue* obj);//先声明
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) 
{if (myCircularQueueIsFull(obj))return false;if (obj->rear!=obj->k)obj->arr[obj->rear++]=value;elseobj->rear=0;obj->arr[obj->k]=value;return true;
}bool myCircularQueueDeQueue(MyCircularQueue* obj) 
{if (myCircularQueueIsEmpty(obj))return false;if (obj->front!=obj->k)obj->front++;elseobj->front=0;return true;}int myCircularQueueFront(MyCircularQueue* obj) 
{if (myCircularQueueIsEmpty(obj))return -1;return obj->arr[obj->front];
}int myCircularQueueRear(MyCircularQueue* obj) 
{if (myCircularQueueIsEmpty(obj))return -1;if (obj->rear)//rear!=0return obj->arr[obj->rear-1];//rear==0return obj->arr[obj->k];
}bool myCircularQueueIsEmpty(MyCircularQueue* obj) 
{return obj->front==obj->rear;
}bool myCircularQueueIsFull(MyCircularQueue* obj) 
{int rear_copy=obj->rear;if (rear_copy+1==obj->front)return true;else if (rear_copy==obj->k && obj->front==0)return true;elsereturn false;
}void myCircularQueueFree(MyCircularQueue* obj) 
{free(obj->arr);free(obj);
}

代码还可以精简些,例如

bool myCircularQueueIsFull(MyCircularQueue* obj) 
{return (obj->rear+1==obj->front) || (obj->rear==obj->k && obj->front==0);
}

提交结果

方法2:每次都取模

★注意:rear++或者front++后一定要取模!

typedef struct 
{int* arr;int front;int rear;int k;
} MyCircularQueue;MyCircularQueue* myCircularQueueCreate(int k) 
{MyCircularQueue* obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));obj->arr=(int*)malloc(sizeof(int)*(k+1));obj->front=obj->rear=0;obj->k=k;return obj;
}bool myCircularQueueIsFull(MyCircularQueue* obj);//先声明
bool myCircularQueueIsEmpty(MyCircularQueue* obj);//先声明
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) 
{if (myCircularQueueIsFull(obj))return false;obj->arr[obj->rear++]=value;obj->rear%=obj->k+1;return true;
}bool myCircularQueueDeQueue(MyCircularQueue* obj) 
{if (myCircularQueueIsEmpty(obj))return false;obj->front++;obj->front%=(obj->k+1);return true;
}int myCircularQueueFront(MyCircularQueue* obj) 
{if (myCircularQueueIsEmpty(obj))return -1;return obj->arr[obj->front];
}int myCircularQueueRear(MyCircularQueue* obj) 
{if (myCircularQueueIsEmpty(obj))return -1;return obj->arr[(obj->rear-1+obj->k+1)%(obj->k+1)];
}bool myCircularQueueIsEmpty(MyCircularQueue* obj) 
{return obj->front==obj->rear;
}bool myCircularQueueIsFull(MyCircularQueue* obj) 
{return (obj->rear+1)%(obj->k+1)==obj->front;
}void myCircularQueueFree(MyCircularQueue* obj) 
{free(obj->arr);free(obj);
}

提交结果

注:有关本题的链表解法参见下一篇

相关文章:

L33.【LeetCode笔记】循环队列(数组解法)

目录 1.题目 2.分析 方法1:链表 尝试使用单向循环链表模拟 插入节点 解决方法1:开辟(k1)个节点 解决方法2:使用变量size记录队列元素个数 获取队尾元素 其他函数的实现说明 方法2:数组 重要点:指针越界的解决方法 方法1:单独判断 方法2:取模 3.数组代码的逐步实现…...

css实现元素垂直居中显示的7种方式

文章目录 * [【一】知道居中元素的宽高](https://blog.csdn.net/weixin_41305441/article/details/89886846#_1) [absolute 负margin](https://blog.csdn.net/weixin_41305441/article/details/89886846#absolute__margin_2) [absolute margin auto](https://blog.csdn.net…...

【Python】Django 中的算法应用与实现

Django 中的算法应用与实现 在 Django 开发中,算法的应用可以极大地扩展 Web 应用的功能和性能。从简单的数据处理到复杂的机器学习模型,Django 都可以作为一个强大的后端框架来支持这些算法的实现。本文将介绍几种常见的算法及其在 Django 中的使用方法…...

Docker 运行 GPUStack 的详细教程

GPUStack GPUStack 是一个用于运行 AI 模型的开源 GPU 集群管理器。它具有广泛的硬件兼容性,支持多种品牌的 GPU,并能在 Apple MacBook、Windows PC 和 Linux 服务器上运行。GPUStack 支持各种 AI 模型,包括大型语言模型(LLMs&am…...

Kubernetes中的 iptables 规则介绍

#作者:邓伟 文章目录 一、Kubernetes 网络模型概述二、iptables 基础知识三、Kubernetes 中的 iptables 应用四、查看和调试 iptables 规则五、总结 在 Kubernetes 集群中,iptables 是一个核心组件, 用于实现服务发现和网络策略。iptables 通…...

解决VScode 连接不上问题

问题 :VScode 连接不上 解决方案: 1、手动杀死VS Code服务器进程,然后重新尝试登录 打开xshell ,远程连接服务器 ,查看vscode的进程 ,然后全部杀掉 [cxqiZwz9fjj2ssnshikw14avaZ ~]$ ps ajx | grep vsc…...

AI 驱动的软件测试革命:从自动化到智能化的进阶之路

🚀引言:软件测试的智能化转型浪潮 在数字化转型加速的今天,软件产品的迭代速度与复杂度呈指数级增长。传统软件测试依赖人工编写用例、执行测试的模式,已难以应对快速交付与高质量要求的双重挑战。人工智能技术的突破为测试领域注…...

【Java代码审计 | 第六篇】XSS防范

文章目录 XSS防范使用HTML转义使用Content Security Policy (CSP)输入验证使用安全的库和框架避免直接使用用户输入构建JavaScript代码 XSS防范 使用HTML转义 在输出用户输入时,对特殊字符进行转义,防止它们被解释为HTML或JavaScript代码。 例如&…...

Android WebSocket工具类:重连、心跳、消息队列一站式解决方案

依赖库 使用 OkHttp 的WebSocket支持。 在 build.gradle 中添加依赖: implementation com.squareup.okhttp3:okhttp:4.9.3WebSocket工具类实现 import okhttp3.*; import android.os.Handler; import android.os.Looper; import android.util.Log;import java.ut…...

认识vue2脚手架

1.认识脚手架结构 使用VSCode将vue项目打开: package.json:包的说明书(包的名字,包的版本,依赖哪些库)。该文件里有webpack的短命令: serve(启动内置服务器) build命令…...

【STM32】STM32系列产品以及新手入门的STM32F103

📢 STM32F103xC/D/E 系列是一款高性能、低功耗的 32 位 MCU,适用于工业、汽车、消费电子等领域;基于 ARM Cortex-M3,主频最高 72MHz,支持 512KB Flash、64KB SRAM,适合复杂嵌入式应用,提供丰富的…...

<建模软件安装教程1>Blender4.2系列

Blender4.2安装教程 0注意:Windows环境下安装 第一步,百度网盘提取安装包。百度网盘链接:通过网盘分享的文件:blender.zip 链接: https://pan.baidu.com/s/1OG0jMMtN0qWDSQ6z_rE-9w 提取码: 0309 --来自百度网盘超级会员v3的分…...

CentOS Docker 安装指南

CentOS Docker 安装指南 引言 Docker 是一个开源的应用容器引擎,它允许开发者打包他们的应用以及应用的依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。Docker 容器是完全使用沙箱机制,相互之…...

分布式ID生成方案:数据库号段、Redis与第三方开源实现

分布式ID生成方案:数据库号段、Redis与第三方开源实现 引言 在分布式系统中,全局唯一ID生成是核心基础能力之一。本文针对三种主流分布式ID生成方案(数据库号段模式、Redis方案、第三方开源框架)进行解析,从实现原理…...

tcc编译器教程2 编译lua解释器

本文主要介绍了使用tcc编译器编译lua解释器源码。 1 介绍 lua是一门编程语言,开源且源码很容易编译,我平时用来测试C语言编程环境时经常使用。一般能编译成功就说明编程环境设置正常。下面用之前设置好的tcc编程环境进行测试。 2 获取源码 我一般有保留多个版本的lua源码进…...

利用 requestrepo 工具验证 XML外部实体注入漏洞

1. 前言 在数字化浪潮席卷的当下,网络安全的重要性愈发凸显。应用程序在便捷生活与工作的同时,也可能暗藏安全风险。XXE(XML外部实体)漏洞作为其中的典型代表,攻击者一旦利用它,便能窃取敏感信息、掌控服务…...

在 Maven 中使用 <scope> 元素:全面指南

目录 前言 在 Maven 中, 元素用于定义依赖项的作用范围,即依赖项在项目生命周期中的使用方式。正确使用 可以帮助我们优化项目的构建过程,减少不必要的依赖冲突,并提高构建效率。本文将详细介绍 的使用步骤、常见作用范围、代码…...

uni_app实现下拉刷新

1. 在页面配置中启用下拉刷新 首先,你需要在页面的 pages.json 文件中启用下拉刷新功能。 {"pages": [{"path": "pages/index/index","style": {"navigationBarTitleText": "首页","enablePull…...

PCIe协议之RCB、MPS、MRRS详解

✨前言: PCIe总线的存储器写请求、存储器读完成等TLP中含有数据负载,即Data Payload。Data Payload的长度和MPS(Max Payload Size)、MRRS(Max Read Request Size)和RCB(Read Completion Bounda…...

达梦数据库在Linux,信创云 安装,备份,还原

(一)系统环境检查 1操作系统:确认使用的是国产麒麟操作系统,检查系统版本是否兼容达梦数据库 V8。可以通过以下命令查看系统版本: cat /etc/os-release 2硬件资源:确保服务器具备足够的硬件资源&#xff0…...

保姆级教程:用iSYSTEM winIDEA和iC5000给S32K148烧录程序,附完整配置流程

从零掌握iSYSTEM工具链:S32K148开发板烧录与调试全流程实战第一次接触iSYSTEM的winIDEA和iC5000仿真器时,很多嵌入式开发者都会感到无从下手。不同于常见的开源工具链,这套专业级开发环境在汽车电子和工业控制领域有着广泛应用,尤…...

四旋翼变形控制:RL与MPC在混合动力学中的对比

1. 四旋翼变形控制的技术挑战与解决方案四旋翼变形控制(Quadrotor Morpho-Transition)是当前机器人领域最具挑战性的前沿技术之一。这项技术使机器人能够在空中完成形态变换,实现从飞行模式到地面模式的平滑切换。想象一下,一架四…...

身份证OCR识别接口接入实战:Python/Java/PHP/C#四语言代码示例与踩坑指南

#身份证OCR, #OCR接口, #API接入, #Python示例, #Java示例, #PHP示例, #踩坑指南, #石榴智能, #实名认证, #图片识别 身份证OCR识别接口接入实战:Python/Java/PHP/C#四语言代码示例与踩坑指南 作者:石榴智能技术团队 一、前言 身份证OCR识别已经不是什…...

DeepSeek基准测试避坑手册:92%开发者忽略的4大陷阱——硬件配置偏差、tokenizer不一致、batch size幻觉、温度值污染

更多请点击: https://codechina.net 第一章:DeepSeek基准测试避坑手册:92%开发者忽略的4大陷阱——硬件配置偏差、tokenizer不一致、batch size幻觉、温度值污染 硬件配置偏差:GPU显存与计算精度的隐性干扰 在A100(8…...

[智能体-81]:工程化智能体 = 模型做脑力拆解 + 框架做流程落地。前者是决策者,后者是管理者,tools/function call是内部员工;mcp server是外部资源;

一、全角色人设 & 对应技术组件角色定位对应技术模块核心职责决策者(脑力大脑)大模型 LLM理解目标、任务拆解、逻辑判断、分支决策、内容生成,负责 “想方案、定步骤”管理者(流程总管)智能体编排框架(…...

PentestGPT实战部署指南:AI驱动的渗透测试工作流落地

1. 这不是另一个“AI安全”的概念玩具,而是一套能真正跑起来的渗透测试辅助工作流“PentestGPT”这个名字刚在GitHub上出现时,我第一反应是点开又关掉——过去三年里,我见过太多打着“AI渗透”旗号的项目:有的只是把ChatGPT API封…...

2026论文降AI怎么挑?亲测好用工具附免费降AI指南

“您的论文AIGC率为42%,超出学校30%的合格线,请修改后重新提交。”赶毕业论文的同学这段时间估计没少收到这样的提醒。2026年知网、万方、维普等主流平台的AI检测算法持续迭代,把AI生成内容改到符合学校要求,已经成了毕业生的刚需…...

从开题到定稿零焦虑:okbiye AI 论文写作,帮你把毕业季的 “大山” 变成坦途

okbiye-免费查重复率aigc检测/开题报告/毕业论文/智能排版/文献综述/AI PPT毕业论文 - Okbiye智能写作https://www.okbiye.com/ai/bylw 毕业季的深夜,宿舍台灯下的屏幕亮着刺眼的光,文档里的字数停留在三位数,而 deadline 正一天天逼近。你是…...

量子纠错码VarQEC:原理、实现与硬件优化

1. 量子纠错码基础与实验背景量子纠错码(Quantum Error Correction Codes, QEC)是量子计算中保护量子信息免受噪声影响的核心技术。与经典纠错码不同,量子纠错需要应对量子态特有的退相干和纠缠特性。传统QEC如[[5,1,3]]完美码虽然理论完备&a…...

终极解决方案:Windows Cleaner免费开源工具,3步彻底解决C盘爆红问题

终极解决方案:Windows Cleaner免费开源工具,3步彻底解决C盘爆红问题 【免费下载链接】WindowsCleaner Windows Cleaner——专治C盘爆红及各种不服! 项目地址: https://gitcode.com/gh_mirrors/wi/WindowsCleaner 你是否也经历过这样的…...