LeetCode題解:641. 設計迴圈雙端佇列,使用佇列,JavaScript,詳細註釋
原題連結:https://leetcode-cn.com/problems/design-circular-deque/
解題思路:
如果你看到這題的時候,感到沒有思路,可以先嚐試其前導題目:622. 設計迴圈佇列,以及我的題解LeetCode題解:622. 設計迴圈佇列,使用陣列,JavaScript,詳細註釋。
建立陣列:
- 先按照佇列的容量,建立相應長度的陣列,所有元素都預設為-1。這樣獲得元素時,只要直接返回即可。
- 使用head指標,指向隊首元素。使用tail指標,指向將要從隊尾插入元素的位置,及隊尾+1。
插入元素:
- 從頭部新增元素時,先將head指標向前移動一位,再將元素插入。從頭部移除元素的操作相反。
- 從尾部新增元素時,先將元素插入到tail指標的位置,再將tail指標向後移動一位。從尾部移除元素的操作相反。
判斷佇列為空或已滿:
- 如果不斷新增元素,最終head指標和tail指標會相遇,此時由於tail指標的位置已有head對應的值佔據,則佇列已滿。
- 如果不斷刪除元素,最終head指標和tail指標會相遇,此時它們指向的位置都為-1,則佇列為空。
在預設用例通過後,可以補充測試如下兩個用例,如果都能通過,那麼這題基本就沒問題了。
["MyCircularDeque","insertFront","getRear","insertFront","getRear","insertLast","getFront","getRear","getFront","insertLast","deleteLast","getFront"]\n[[3],[9],[],[9],[],[5],[],[],[],[8],[],[]]
["MyCircularDeque","insertFront","deleteLast","getRear","getFront","getFront","deleteFront","insertFront","insertLast","insertFront","getFront","insertFront"]\n[[4],[9],[],[],[],[],[],[6],[5],[9],[],[6]]
/**
* Initialize your data structure here. Set the size of the deque to be k.
* @param {number} k
*/
var MyCircularDeque = function (k) {
// 佇列的容量
this.capacity = k;
// 使用陣列存放佇列元素,所有的初始值都是-1,取值的時候直接返回
this.queue = new Array(k).fill(-1);
// 佇列的頭指標,即佇列頭元素的位置
this.head = 0;
// 佇列的尾指標,即尾部要插入元素的位置,也就是佇列的尾元素的位置+1
this.tail = 0;
};
// 將index-1,需要考慮index到達陣列首尾時需要迴圈
MyCircularDeque.prototype.reduceIndex = function (index) {
return (index + this.capacity - 1) % this.capacity;
};
// 將index+1,需要考慮index到達陣列首尾時需要迴圈
MyCircularDeque.prototype.addIndex = function (index) {
return (index + 1) % this.capacity;
};
/**
* Adds an item at the front of Deque. Return true if the operation is successful.
* @param {number} value
* @return {boolean}
*/
MyCircularDeque.prototype.insertFront = function (value) {
// 判斷佇列是否已滿
if (this.isFull()) {
return false;
}
// 從頭部插入元素時,要先將頭指標向前移動一位
this.head = this.reduceIndex(this.head);
// 在新的頭指標位置插入元素
this.queue[this.head] = value;
return true;
};
/**
* Adds an item at the rear of Deque. Return true if the operation is successful.
* @param {number} value
* @return {boolean}
*/
MyCircularDeque.prototype.insertLast = function (value) {
// 判斷佇列是否已滿
if (this.isFull()) {
return false;
}
// 在尾指標的位置插入元素
this.queue[this.tail] = value;
// 將尾指標向後移動一位,指向下一次插入元素的位置
this.tail = this.addIndex(this.tail);
return true;
};
/**
* Deletes an item from the front of Deque. Return true if the operation is successful.
* @return {boolean}
*/
MyCircularDeque.prototype.deleteFront = function () {
// 判斷佇列是否為空
if (this.isEmpty()) {
return false;
}
// 將頭指標的值置為-1,表示元素被刪除
this.queue[this.head] = -1;
// 刪除元素後,要將頭指標向後移動一位
this.head = this.addIndex(this.head);
return true;
};
/**
* Deletes an item from the rear of Deque. Return true if the operation is successful.
* @return {boolean}
*/
MyCircularDeque.prototype.deleteLast = function () {
// 判斷佇列是否為空
if (this.isEmpty()) {
return false;
}
// 先將尾指標向前移動一位,指向隊尾元素
this.tail = this.reduceIndex(this.tail);
// 將隊尾元素設定為-1
this.queue[this.tail] = -1;
return true;
};
/**
* Get the front item from the deque.
* @return {number}
*/
MyCircularDeque.prototype.getFront = function () {
// 直接返回頭指標的元素即可,由於初始值是-1,因此如果佇列為空,會返回-1
return this.queue[this.head];
};
/**
* Get the last item from the deque.
* @return {number}
*/
MyCircularDeque.prototype.getRear = function () {
// 直接返回尾指標-1的元素即可,由於初始值是-1,因此如果佇列為空,會返回-1
return this.queue[this.reduceIndex(this.tail)];
};
/**
* Checks whether the circular deque is empty or not.
* @return {boolean}
*/
MyCircularDeque.prototype.isEmpty = function () {
// 如果頭尾指標的位置相同,且對應位置的值為-1,表示佇列中已無元素,則為空
return this.head === this.tail && this.queue[this.head] < 0;
};
/**
* Checks whether the circular deque is full or not.
* @return {boolean}
*/
MyCircularDeque.prototype.isFull = function () {
// 如果頭尾指標的位置相同,且對應位置的值不為-1,此時無法再插入元素,則佇列已滿
return this.head === this.tail && this.queue[this.head] >= 0;
};
相關文章
- 佇列 和 迴圈佇列佇列
- LeetCode 迴圈佇列LeetCode佇列
- 單調佇列雙端佇列佇列
- 佇列 手算到機算 入門 佇列 迴圈佇列佇列
- 雙端佇列佇列
- 佇列的一種實現:迴圈佇列佇列
- 順序迴圈佇列的介面設計佇列
- 迴圈佇列的實現及細節佇列
- Java版-資料結構-佇列(迴圈佇列)Java資料結構佇列
- 佇列的順序儲存--迴圈佇列的建立佇列
- 迴圈佇列的基本操作佇列
- 佇列-單端佇列佇列
- 靜態佇列,迴圈陣列實現佇列陣列
- 三、資料結構演算法-棧、佇列、優先佇列、雙端佇列資料結構演算法佇列
- 事件迴圈與任務佇列事件佇列
- 迴圈佇列C++實現佇列C++
- 資料結構——迴圈佇列PTA習題資料結構佇列
- 手擼MQ訊息佇列——迴圈陣列MQ佇列陣列
- 【資料結構】迴圈佇列的front,rear指標以及佇列滿的條件、計算佇列長度資料結構佇列指標
- ArrayDeque雙端佇列 使用&實現原理分析佇列
- C 語言使用非迴圈雙向連結串列實現佇列佇列
- c/c++線性迴圈佇列C++佇列
- 詳細瞭解IDM的佇列功能佇列
- 同步容器、併發容器、阻塞佇列、雙端佇列與工作密取佇列
- 自定義單連結串列佇列的基本介面函式(非迴圈佇列)佇列函式
- 圖解--佇列、併發佇列圖解佇列
- Throwing cards away I(queue迴圈佇列)佇列
- C 語言實現使用靜態陣列實現迴圈佇列陣列佇列
- C 語言實現使用動態陣列實現迴圈佇列陣列佇列
- 最詳細版圖解優先佇列(堆)圖解佇列
- 資料結構之「雙端佇列」資料結構佇列
- python雙端佇列的原理分析Python佇列
- PTA 雙端佇列 資料結構佇列資料結構
- hdu5380 貪心+雙端佇列佇列
- 訊息佇列ActiveMQ的使用詳解佇列MQ
- 【雙端佇列】例題6-1 UVa 210佇列
- 佇列、阻塞佇列佇列
- python資料結構與演算法——棧、佇列與雙端佇列Python資料結構演算法佇列