每日一题(设计循环队列)

简介: 每日一题(设计循环队列)

每日一题(设计循环队列)


622. 设计循环队列 - 力扣(LeetCode)


1beacc3f144b5e2ea3f011dba50bf102_7fbcdeb8d68244a3b00871bf02e85c18.png


1.题意解读

本题只能为队列开辟k个单位空间,并且只能利用这几个空间进行数据的存储。


思路:本题使用数组来实现队列是比较方便的,首先定义两个变量:front和rear变量。分别用于记录队头和队尾。一开始初始化时让front和rear都指向数组的第一个位置,存储数据时,按着下图的方式,向rear下标处存储数据,存储成功之后rear自加1,也就是意味着rear始终指向的当前队尾元素的下一个位置。


分析:假设k的值是5,那么本来应该就是开辟5个空间。但是我用的这种方法需要多开辟一个单位的空间。为什么呢?假若我们开辟的是5的单位的空间,那么当存满了k个数据之后,此时的rear和front就都指向了数组中的第一个元素。那么请仔细想想,在初始化的时候我们也将rear和front也初始化为了0,也指向了数组中的第一个元素。那么在这两种情况下,front和rear都指向了数组的第一个元素,但是队列中的元素个数却是大不相同,无法将队列为满和队列为空进行分开。为了避免这种问题的发生,这里多开辟一个空间,当rear下标的下一个位置是front时,此时队列中存储了k个元素,也就说明了队列已满,那么同时判断队列为空就很方便了。只要rear与front相等时,队列就为空。


删除队头元素:删除队头的元素就只需要将front++即可。


c985ba9a5a9b114cdcff1660f6e75b7f_61e367c17aed4caab5dcf96277d9e9f5.gif


注意:


  • 当遇到了非常规情况时:rear到了队尾需要循环到队头时,则只需要执行语句 rear++;rear %= k+1;这两条语句即可。针对front到达队尾需要到达队头的情况也同样适用的。
  • 当需要获取队尾的元素时,实际上获取的是rear的前一个下标处的值,需要访问rear-1下标处的值,但是假若此时的rear的值是0,那么此时需要特判以下,假如rear的值是0时,直接访问k下标处的值即可。rear的值不为0时,只需要正常访问rear-1下标处的元素即可。


f7dfaaebe6269ac0aeffa4b1b32e79cc_0d987b7a22254318a5d002c50391628e.gif


代码实现:

typedef struct {
    int* a;
    int front;
    int rear;
    int k;
} MyCircularQueue;
MyCircularQueue* myCircularQueueCreate(int k) {
MyCircularQueue*  obj = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
    obj->a = (int*)malloc(sizeof(int)*(k+1));
    obj->front = 0;
    obj->rear = 0;
    obj->k = k;
    return obj;
}
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
    assert(obj);
    return ((obj->rear)==(obj->front));
}
bool myCircularQueueIsFull(MyCircularQueue* obj) {
        assert(obj);
    return (((obj->rear+1)%(obj->k+1))==(obj->front));
}
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
    assert(obj);
    if(!myCircularQueueIsFull(obj))//未满
    {
        obj->a[obj->rear] = value;
        obj->rear++;
        obj->rear %= (obj->k+1);
        return true;
    }
    return false;
}
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
    assert(obj);
    if(!myCircularQueueIsEmpty(obj))//非空
    {
        obj->front++;
        obj->front %=obj->k+1;
        return true;
    }
    return false;
}
int myCircularQueueFront(MyCircularQueue* obj) {
    assert(obj);
    if(myCircularQueueIsEmpty(obj))
    {
        return -1;
    }
    return obj->a[obj->front];
}
int myCircularQueueRear(MyCircularQueue* obj) {
        assert(obj);
    if(myCircularQueueIsEmpty(obj))
    {
        return -1;
    }
    if(obj->rear == 0)
        return obj->a[obj->k];
    else
    {
         return obj->a[obj->rear-1];
    }
}
void myCircularQueueFree(MyCircularQueue* obj) {
    assert(obj);
    free(obj->a);
    free(obj);
    obj=NULL;
}


完结


设计循环队列的分析就到这里啦,若有不足,欢迎评论区指正,下期见!


相关文章
|
人工智能 搜索推荐 大数据
EDM营销是什么意思?
EDM营销是什么意思?
swagger3.0中,如何在@GetMapping中写多个参数,包括数组类型的参数
swagger3.0中,如何在@GetMapping中写多个参数,包括数组类型的参数
735 0
|
SQL 存储 关系型数据库
SQL语言优缺点有哪些?
SQL(Structured Query Language)语言作为数据库管理和操作的标准语言,具有一系列的优点,同时也存在一些缺点。
392 7
|
前端开发 数据挖掘 数据建模
课程视频|R语言bnlearn包:贝叶斯网络的构造及参数学习的原理和实例(中)
课程视频|R语言bnlearn包:贝叶斯网络的构造及参数学习的原理和实例
|
人工智能 监控 Python
[AI Embedchain] 集成 Langsmith
[AI Embedchain] 集成 Langsmith
[AI Embedchain] 集成 Langsmith
|
人工智能 自然语言处理 搜索推荐
DeepMind终结大模型幻觉?标注事实比人类靠谱、还便宜20倍,全开源
【4月更文挑战第5天】DeepMind推出开源工具SAFE,挑战大模型的幻觉,提升事实评估准确性和效率。通过自动化和搜索引擎验证,SAFE在成本上比人类标注便宜20倍,且在72%的时间与人类一致,显示了在大规模事实验证中的潜力。然而,依赖谷歌搜索和易受长文本信息过载影响是其局限性。
294 13
DeepMind终结大模型幻觉?标注事实比人类靠谱、还便宜20倍,全开源
|
Linux 开发工具 数据安全/隐私保护
【Deepin 20 系统】error:driver pcspkr is already registered aborting
解决Deepin 20系统启动时遇到的“error: driver pcspkr is already registered aborting”错误的方法,通过在GRUB引导加载器中临时更改启动选项进入多用户文本模式,并在系统中创建一个黑名单文件来禁用pcspkr驱动。
801 2
|
JavaScript 前端开发 IDE
Vue3【为什么选择Vue框架、Vue简介 、Vue API 风格 、Vue开发前的准备 、Vue项目目录结构 、模板语法、属性绑定 、 】(一)-全面详解(学习总结---从入门到深化)
Vue3【为什么选择Vue框架、Vue简介 、Vue API 风格 、Vue开发前的准备 、Vue项目目录结构 、模板语法、属性绑定 、 】(一)-全面详解(学习总结---从入门到深化)
345 1
|
消息中间件 Java 应用服务中间件
Github上365道Java高频面试复习题,助你吊打面试官
无论如何在这两个月的跳槽黄金期 筹备面试是最重要的了,你有规划好自己的复习方向了吗?