【LeetCode每日一題】——622.設計迴圈佇列
阿新 • • 發佈:2021-05-14
文章目錄
一【題目類別】
- 佇列
二【題目難度】
- 中等
三【題目編號】
- 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(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)
九【程式碼實現】
- 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; // 這是迴圈佇列的核心,取模就是轉了一圈,預留一個元素位置
}
}
- 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);
}
/*主函式省略*/
十【提交結果】
- Java語言版
- C語言版