【Leetcode】1670. Design Front Middle Back Queue

記錄演算法發表於2020-11-29

題目地址:

https://leetcode.com/problems/design-front-middle-back-queue/

要求設計一個雙端佇列,除了要實現隊首隊尾新增刪除元素之外,還需要實現從中間新增刪除的操作。中間的定義是,如果整個佇列有偶數個元素,則取靠近隊頭的那個中間元素。在中間新增元素時,如果元素個數奇數個,則在正中間元素之前新增元素。如果執行pop的時候佇列空,則返回 − 1 -1 1

思路是用兩個雙端佇列,一個存前半部分元素,一個存後半部分元素。同時,我們保持後半部分元素個數不少於前半部分,並且比前半部分最多多一個。這樣在pushMiddle的時候永遠都是向前佇列隊尾插入元素;popMiddle的時候要判斷下兩個佇列size是否一樣,如果一樣則pop前佇列隊尾,否則pop後佇列隊頭;這裡需要注意,popFront的時候要看一下前佇列是否為空,否則會NPE。程式碼如下:

import java.util.ArrayDeque;
import java.util.Deque;

class FrontMiddleBackQueue {
    
    private Deque<Integer> fDeq, rDeq;
    private int size;
    
    public FrontMiddleBackQueue() {
        fDeq = new ArrayDeque<>();
        rDeq = new ArrayDeque<>();
    }
    
    public void pushFront(int val) {
        fDeq.offerFirst(val);
        adjust();
        size++;
    }
    
    public void pushMiddle(int val) {
        fDeq.offerLast(val);
        adjust();
        size++;
    }
    
    public void pushBack(int val) {
        rDeq.offerLast(val);
        adjust();
        size++;
    }
    
    public int popFront() {
        if (size == 0) {
            return -1;
        }
        
        // 注意要判斷一下前佇列是否空
        int res = !fDeq.isEmpty() ? fDeq.pollFirst() : rDeq.pollFirst();
        adjust();
        size--;
        return res;
    }
    
    public int popMiddle() {
        if (size == 0) {
            return -1;
        }
        
        // 如果兩個佇列size一樣,則pop前佇列隊尾,否則pop後佇列隊頭
        int res = fDeq.size() == rDeq.size() ? fDeq.pollLast() : rDeq.pollFirst();
        adjust();
        size--;
        return res;
    }
    
    public int popBack() {
        if (size == 0) {
            return -1;
        }
        
        int res = rDeq.pollLast();
        adjust();
        size--;
        return res;
    }
    
    // 用於調整兩個佇列的size,保持後半始終不少於前半,並且多不超過1個
    private void adjust() {
        if (rDeq.size() - fDeq.size() >= 2) {
            fDeq.offerLast(rDeq.pollFirst());
        }
        if (rDeq.size() < fDeq.size()) {
            rDeq.offerFirst(fDeq.pollLast());
        }
    }
}

所有操作時間複雜度 O ( 1 ) O(1) O(1),空間 O ( n ) O(n) O(n) n n n是新增進了多少個元素。

相關文章