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] 。

使用一个双向队列,可以实现 在头尾的插入和删除。

使用两个双向队列,可以实现 在头尾和中间的插入。

左双向队列和右双向队列长度相等或左双向队列长度为右双向队列长度减1。

插入删除头尾后,需要维护一个两个队列的长度。

插入中间时,插入到左队列尾部;删除中间时,删除右队列头部。

弹出头部和尾部时,判断左队列和右队列是否为空。

class FrontMiddleBackQueue {
public:
    deque<int>left;
    deque<int>right;
    void balance(){
        if(left.size()>right.size()){
            right.push_front(left.back());
            left.pop_back();
        }else if(right.size()>left.size()+1){
            left.push_back(right.front());
            right.pop_front();
        }
    }
    FrontMiddleBackQueue() {

    }
    
    void pushFront(int val) {
        left.push_front(val);
        balance();
    }
    
    void pushMiddle(int val) {
        if(left.size()<right.size()){
            left.push_back(val);
        }else{
            right.push_front(val);
        }
    }
    
    void pushBack(int val) {
        right.push_back(val);
        balance();
    }    
    int popFront() {
        if(right.empty()){
            return -1;
        }
        int val;
        if(left.empty()){
            val=right.front();
            right.pop_front();
        }else{
            val=left.front();
            left.pop_front();
        }
        balance();
        return val;
    }
    int popMiddle() {
        if(right.empty()){
            return -1;
        }
        int val;
        if(left.size()==right.size()){
            val=left.back();
            left.pop_back();
        }else{
            val=right.front();
            right.pop_front();
        }
        return val;
    }
    int popBack() {
        if(right.empty()){
            return -1;
        }
        int val = right.back();
        right.pop_back();
        balance();
        return val;
    }
};

/**
 * Your FrontMiddleBackQueue object will be instantiated and called as such:
 * FrontMiddleBackQueue* obj = new FrontMiddleBackQueue();
 * obj->pushFront(val);
 * obj->pushMiddle(val);
 * obj->pushBack(val);
 * int param_4 = obj->popFront();
 * int param_5 = obj->popMiddle();
 * int param_6 = obj->popBack();
 */
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.