1. 程式人生 > 其它 >【LeetCode每日一題】——622.設計迴圈佇列

【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語言版
    在這裡插入圖片描述