1. 程式人生 > 其它 >[連結串列]leetcode1670-設計前中後佇列

[連結串列]leetcode1670-設計前中後佇列

技術標籤:leetcode# leetcode-連結串列佇列連結串列javaleetcode

[連結串列]–設計前中後佇列


題目連結

leetcode 1670.設計前中後佇列

題目

請你設計一個佇列,支援在前,中,後三個位置的 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;
        }
    }
}

-----------------------------------------------------------------------------有始有終分割線----------------------------------------------------------------------------------