【LeetCode每日一题】——622.设计循环队列

一【题目类别】

  • 队列

二【题目难度】

  • 中等

三【题目编号】

  • 622.设计循环队列

四【题目描述】

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

七【解题思路】

  • 此题没有难度,不再赘述

八【时间频度】

  • 时间复杂度: O ( 1 ) O(1) O(1)

九【代码实现】

  1. Java语言版
package Queue;

public class P622_DesignCircularQueue {

    private static int[] queue; // 数组模拟队列
    private static int len; // 需要生成的长度
    private static int front; // 队列头指针
    private static int rear; // 队列尾指针

    public static void main(String[] args) {
        P622_DesignCircularQueue res1 = new P622_DesignCircularQueue(3);
        boolean res2 = enQueue(1);
        boolean res3 = enQueue(2);
        boolean res4 = enQueue(3);
        boolean res5 = enQueue(4);
        int res6 = Rear();
        boolean res7 = isFull();
        boolean res8 = deQueue();
        boolean res9 = enQueue(4);
        int res10 = Rear();
        System.out.println(res1 + " " + res2 + " " + res3 + " " + res4 + " " + res5 + " " + res6 + " " + res7 + " " + res8 + " " + res9 + " " + res10);
    }

    // 初始化队列
    public P622_DesignCircularQueue(int k) {
        len = k + 1; // 这里+1是因为要预留一个元素位置
        queue = new int[len];
    }

    // 向队列插入元素
    public static boolean enQueue(int value) {
        if (isFull()) {
            return false;
        }
        queue[rear] = value;
        rear = (rear + 1) % len; // 取模就是转了一圈,如果到了队列最后一个,那么下一个就到了队列头
        return true;
    }

    // 弹出队列头元素
    public static boolean deQueue() {
        if (isEmpty()) {
            return false;
        }
        front = (front + 1) % len; // 取模就是转了一圈,如果到了队列最后一个,那么下一个就到了队列头
        return true;
    }

    // 得到队列头元素
    public static int Front() {
        if (isEmpty()) {
            return -1;
        }
        return queue[(front + len) % len]; // 因为头指针指哪就是哪,所以直接返回,但是涉及到转圈的问题
    }

    // 得到队列尾元素
    public static int Rear() {
        if (isEmpty()) {
            return -1;
        }
        return queue[(rear - 1 + len) % len]; // 因为尾指针最后一次+1了,所以队尾元素要-1,但是涉及到转圈的问题
    }

    // 判断队列是否空
    public static boolean isEmpty() {
        return rear == front;
    }

    // 判断队列是否满
    public static boolean isFull() {
        return (rear + 1) % len == front; // 这是循环队列的核心,取模就是转了一圈,预留一个元素位置
    }

}
  1. C语言版
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdbool.h>

/*循环队列结构体*/
typedef struct
{
	int *data; /*数组模拟队列*/
	int front; /*头指针*/
	int rear; /*尾指针*/
	int len; /*数组长度*/
}MyCircularQueue;

/*初始化队列*/
MyCircularQueue* myCircularQueueCreate(int k)
{
	MyCircularQueue* queue = (MyCircularQueue *)malloc(sizeof(MyCircularQueue));
	queue->data = (int *)malloc((k + 1) * sizeof(int));
	queue->front = 0;
	queue->rear = 0;
	queue->len = k + 1; /*这里+1是因为要预留一个元素位置*/
	return queue;
}

/*判断队列是否空*/
bool myCircularQueueIsEmpty(MyCircularQueue* obj)
{
	return obj->rear == obj->front;
}

/*判断队列是否满*/
bool myCircularQueueIsFull(MyCircularQueue* obj)
{
	return (obj->rear + 1) % obj->len == obj->front;
}

/*向队列插入元素*/
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value)
{
	if (myCircularQueueIsFull(obj))
	{
		return false;
	}
	obj->data[obj->rear] = value;
	obj->rear = (obj->rear + 1) % obj->len; /*取模就是转了一圈,如果到了队列最后一个,那么下一个就到了队列头*/
	return true;
}

/*弹出队列头元素*/
bool myCircularQueueDeQueue(MyCircularQueue* obj)
{
	if (myCircularQueueIsEmpty(obj))
	{
		return false;
	}
	obj->front = (obj->front + 1) % obj->len; /*取模就是转了一圈,如果到了队列最后一个,那么下一个就到了队列头*/
	return true;
}

/*得到队列头元素*/
int myCircularQueueFront(MyCircularQueue* obj)
{
	if (myCircularQueueIsEmpty(obj))
	{
		return -1;
	}
	return obj->data[(obj->front + obj->len) % obj->len]; /*因为头指针指哪就是哪,所以直接返回,但是涉及到转圈的问题*/
}

/*得到队列尾元素*/
int myCircularQueueRear(MyCircularQueue* obj)
{
	if (myCircularQueueIsEmpty(obj))
	{
		return -1;
	}
	return obj->data[(obj->rear - 1 + obj->len) % obj->len]; /*因为尾指针最后一次+1了,所以队尾元素要-1,但是涉及到转圈的问题*/
}

/*释放元素*/
void myCircularQueueFree(MyCircularQueue* obj)
{
	free(obj->data); /*注意这里要先释放队列数组,再释放整个队列,否则会出现数组越界情况*/
	free(obj);
}

/*主函数省略*/

十【提交结果】

  1. Java语言版
    在这里插入图片描述
  2. C语言版
    在这里插入图片描述
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IronmanJay

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值