1670. Design Front Middle Back Queue

1670. Design Front Middle Back Queue #

题目 #

请你设计一个队列,支持在前,中,后三个位置的 pushpop 操作。

请你完成 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

思路 #

代码 #

class FrontMiddleBackQueue {

    private class ListNode {
        int val;
        ListNode prev;
        ListNode next;

        ListNode(int value, ListNode prev, ListNode next) {
            this.val = value;
            this.prev = prev;
            this.next = next;
        }
    }

    private int size;
    ListNode sentinel;
    ListNode middle;

    public FrontMiddleBackQueue() {
        this.size = 0;
        this.sentinel = new ListNode(-1, null, null);
        this.sentinel.prev = this.sentinel.next = this.sentinel;

        this.middle = this.sentinel;
    }
    
    public void pushFront(int val) {
        this.sentinel.next = new ListNode(val, this.sentinel, this.sentinel.next);
        this.sentinel.next.next.prev = this.sentinel.next;

        /** 对于 pushFront 操作:
         *  若插入前链表长度为偶数,则 middle 指针不移动
         *  若插入前链表长度为奇数,则 middle 指针需向前移动一位
         */
        if (this.size == 0) this.middle = this.sentinel.next;
        else if (this.size % 2 == 1) this.middle = this.middle.prev;

        this.size += 1;
    }
    
    public void pushMiddle(int val) {
        if (this.size == 0) {
            this.sentinel.next = new ListNode(val, this.sentinel, this.sentinel);
            this.sentinel.prev = this.sentinel.next;
            this.middle = this.sentinel.next;
            this.size += 1;
        }
        else if (this.size % 2 == 1) {
            this.middle.prev.next = new ListNode(val, this.middle.prev, this.middle);
            this.middle.prev = this.middle.prev.next;
            this.middle = this.middle.prev;
            this.size += 1;
        }
        else {
            this.middle.next = new ListNode(val, this.middle, this.middle.next);
            this.middle.next.next.prev = this.middle.next;
            this.middle = this.middle.next;
            this.size += 1;
        }
    }
    
    public void pushBack(int val) {
        this.sentinel.prev = new ListNode(val, this.sentinel.prev, this.sentinel);
        this.sentinel.prev.prev.next = this.sentinel.prev;

        /** 对于 pushBack 操作:
         *  若插入前链表长度为偶数,则 middle 指针需向后移动一位
         *  若插入前链表长度为奇数,则 middle 指针不移动
         */
         if (this.size == 0) this.middle = this.sentinel.next;
         else if (this.size % 2 == 0) this.middle = this.middle.next;

        this.size += 1;
    }
    
    public int popFront() {
        if (this.size == 0) return -1;

        int result = this.sentinel.next.val;

        this.sentinel.next = this.sentinel.next.next;
        this.sentinel.next.prev = this.sentinel;

        if (this.size == 1) this.middle = this.sentinel;
        else if (this.size % 2 == 0) this.middle = this.middle.next;

        this.size -= 1;
        return result;
    }
    
    public int popMiddle() {
        if (this.size == 0) return -1;

        int result = this.middle.val;

        this.middle.prev.next = this.middle.next;
        this.middle.next.prev = this.middle.prev;

        if (this.size == 1) this.middle = this.sentinel;
        else if (this.size % 2 == 0) this.middle = this.middle.next;
        else if (this.size % 2 == 1) this.middle = this.middle.prev;

        this.size -= 1;
        return result;
    }
    
    public int popBack() {
        if (this.size == 0) return -1;

        int result = this.sentinel.prev.val;

        this.sentinel.prev = this.sentinel.prev.prev;
        this.sentinel.prev.next = this.sentinel;

        if (this.size == 1) this.middle = this.sentinel;
        else if (this.size % 2 == 1) this.middle = this.middle.prev;

        this.size -= 1;
        return result;
    }
}