设计循环队列

805 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第5天,点击查看活动详情

一、题目

LeetCode 设计循环队列

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

二、题解

按题目要求设计一个满足条件的循环队列,并且完成各种操作队列的方法。

方法一

首先可以用一个数组来当成一个队列,然后用一个变量记录队列长度,然后还需要记录下队列的队头和队尾元素。 设计队列中需要的属性有四个,首先需要的是整形的一个数组nums、还有一个变量记录队列的大小size、同时也得记录队列的位置即队列的头部head和队列的尾部tail。队列的方法MyCircularQueue(int k)构造器需要初始化队列,初始化设置nums数组的大小为参数k大小,并且设置size队列大小属性;方法enQueue(int value)需要在队列插入一个元素,如果队列已满则不能新增元素,否则往数组指定位置tail % size新增元素,然后移动尾部指针;方法deQueue()需要从队列中删除一个元素,如果队列元素为空则无法删除元素,否则移动头部指针删除元素;方法Front()获取队列头部元素,如果队列元素为空则返回-1,否则返回数组中头部指针head % size元素;方法Rear()获取队列尾部元素,如果队列元素为空则返回-1,否则返回数组中尾部指针(tail - 1) % size元素;方法isEmpty()判断队列是否为空,判断头部尾部指针是否相同;方法isFull()需要判断队列是否已满即可。

三、代码

方法一 Java代码

class MyCircularQueue {
    int[] nums;
    int size;
    int head;
    int tail;

    public MyCircularQueue(int size) {
        nums = new int[size];
        this.size = size;
    }

    public boolean enQueue(int value) {
        if (isFull()) return false;
        nums[tail % size] = value;
        return ++tail >= 0;
    }

    public boolean deQueue() {
        if (isEmpty()) return false;
        return ++head >= 0;
    }

    public int Front() {
        return isEmpty() ? -1 : nums[head % size];
    }

    public int Rear() {
        return isEmpty() ? -1 : nums[(tail - 1) % size];
    }

    public boolean isEmpty() {
        return head == tail;
    }

    public boolean isFull() {
        return tail - head == size;
    }
}

时间复杂度:O(1)。

空间复杂度:O(n),需要一个数组来充当队列。