[連結串列]leetcode1670-設計前中後佇列
阿新 • • 發佈:2020-12-15
技術標籤:leetcode# leetcode-連結串列佇列連結串列javaleetcode
[連結串列]–設計前中後佇列
題目連結
題目
請你設計一個佇列,支援在前,中,後三個位置的 push 和 pop 操作。
請你完成 FrontMiddleBack 類:
- FrontMiddleBack() 初始化佇列。
- void pushFront(int val) 將 val 新增到佇列的 最前面 。
- void pushMiddle(int val) 將 val 新增到佇列的 正中間 。
- void pushBack(int val) 將 val 新增到隊裡的 最後面 。
- int popFront() 將 最前面 的元素從佇列中刪除並返回值,如果刪除之前佇列為空,那麼返回 -1 。
- int popMiddle() 將 正中間 的元素從佇列中刪除並返回值,如果刪除之前佇列為空,那麼返回 -1 。
- int popBack() 將 最後面 的元素從佇列中刪除並返回值,如果刪除之前佇列為空,那麼返回 -1 。
請注意當有 兩個 中間位置的時候,選擇靠前面的位置進行操作。比方說:
將 6 新增到 [1, 2, 3, 4, 5] 的中間位置,結果陣列為 [1, 2, 6, 3, 4, 5] 。
從 [1, 2, 3, 4, 5, 6] 的中間位置彈出元素,返回 3 ,陣列變為 [1, 2, 4, 5, 6] 。
示例
輸入: ["FrontMiddleBackQueue", "pushFront", "pushBack", "pushMiddle", "pushMiddle", "popFront", "popMiddle", "popMiddle", "popBack", "popFront"] [[], [1], [2], [3], [4], [], [], [], [], []] 輸出: [null, null, null, null, null, 1, 3, 4, 2, -1] 解釋: FrontMiddleBackQueue q = new FrontMiddleBackQueue(); q.pushFront(1); // [1] q.pushBack(2); // [1, 2] q.pushMiddle(3); // [1, 3, 2] q.pushMiddle(4); // [1, 4, 3, 2] q.popFront(); // 返回 1 -> [4, 3, 2] q.popMiddle(); // 返回 3 -> [4, 2] q.popMiddle(); // 返回 4 -> [2] q.popBack(); // 返回 2 -> [] q.popFront(); // 返回 -1 -> [] (佇列為空)
解析
看到就想到之 List實現
程式碼實現
public class Solution1670 {
/**
* 使用 list 設計前中後佇列
*/
class FrontMiddleBackQueue {
List<Integer> list;
/** 初始化佇列 */
public FrontMiddleBackQueue() {
list = new ArrayList<>(1000);
}
/** 將 val 新增到佇列的 最前面 */
public void pushFront(int val) {
list.add(0, val);
}
/** 將 val 新增到佇列的 正中間 */
public void pushMiddle(int val) {
int middle = list.size()/2;
list.add(middle, val);
}
/** 將 val 新增到佇列的 最後面 */
public void pushBack(int val) {
list.add(list.size(), val);
}
/** 將 最前面 的元素從佇列中刪除並返回值,如果刪除之前佇列為空,那麼返回 -1 */
public int popFront() {
if (list.isEmpty()) {
return -1;
}
return list.remove(0);
}
/** 將 正中間 的元素從佇列中刪除並返回值,如果刪除之前佇列為空,那麼返回 -1 */
public int popMiddle() {
if (list.isEmpty()) {
return -1;
}
return list.remove((list.size()-1) / 2);
}
/** 將 最後面 的元素從佇列中刪除並返回值,如果刪除之前佇列為空,那麼返回 -1 */
public int popBack() {
if (list.isEmpty()) {
return -1;
}
return list.remove(list.size()-1);
}
}
}
躍躍欲試之 雙向連結串列實現!還沒 List 快?實現過程可能存在問題
程式碼實現
public class Solution1670 {
/**
* Definition for doubly-linked list
*/
class ListNode {
int val;
ListNode prev;
ListNode next;
public ListNode(int val) {
this.val = val;
}
}
/**
* 使用 雙向連結串列 設計前中後佇列
*/
class FrontMiddleBackQueue {
ListNode head;// 虛擬頭節點
ListNode middle;// 中間節點
ListNode tail;// 虛擬尾結點
int size;
/** 初始化佇列 */
public FrontMiddleBackQueue() {
this.size = 0;
head = new ListNode(0);
tail = new ListNode(0);
this.head.next = this.tail;
this.tail.prev = this.head;
}
/** 查詢中間節點 */
public ListNode findPushMiddle() {
ListNode pHead = this.head;
ListNode pTail = this.tail;
while (pHead != pTail && pHead.next != pTail) {
pHead = pHead.next;
pTail = pTail.prev;
}
return pTail;
}
public ListNode findPpoMiddle() {
ListNode pHead = this.head;
ListNode pTail = this.tail;
while (pHead != pTail && pHead.next != pTail) {
pHead = pHead.next;
pTail = pTail.prev;
}
return pHead;
}
/** 將 val 新增到佇列的 最前面 */
public void pushFront(int val) {
ListNode prev = this.head;
ListNode next = prev.next;
ListNode node = new ListNode(val);
prev.next = node;
node.next = next;
next.prev = node;
node.prev = prev;
}
/** 將 val 新增到佇列的 正中間 */
public void pushMiddle(int val) {
ListNode middle = findPushMiddle();
ListNode prev = middle.prev;
ListNode node = new ListNode(val);
prev.next = node;
node.next = middle;
middle.prev = node;
node.prev = prev;
}
/** 將 val 新增到佇列的 最後面 */
public void pushBack(int val) {
ListNode next = this.tail;
ListNode prev = next.prev;
ListNode node = new ListNode(val);
prev.next = node;
node.next = next;
next.prev = node;
node.prev = prev;
}
/** 將 最前面 的元素從佇列中刪除並返回值,如果刪除之前佇列為空,那麼返回 -1 */
public int popFront() {
if (this.head == findPpoMiddle()) {
return -1;
}
int front = this.head.next.val;
ListNode next = this.head.next.next;
this.head.next = next;
next.prev = this.head;
return front;
}
/** 將 正中間 的元素從佇列中刪除並返回值,如果刪除之前佇列為空,那麼返回 -1 */
public int popMiddle() {
ListNode middle = findPpoMiddle();
if (this.head == middle) {
return -1;
}
ListNode prev = middle.prev;
ListNode next = middle.next;
prev.next = next;
next.prev = prev;
return middle.val;
}
/** 將 最後面 的元素從佇列中刪除並返回值,如果刪除之前佇列為空,那麼返回 -1 */
public int popBack() {
if (this.head == findPpoMiddle()) {
return -1;
}
int back = this.tail.prev.val;
ListNode prev = this.tail.prev.prev;
this.tail.prev = prev;
prev.next = this.tail;
return back;
}
}
}
-----------------------------------------------------------------------------有始有終分割線----------------------------------------------------------------------------------