JAVA O(1) DoubleLinkedList Easy Understand
\nclass FrontMiddleBackQueue {\n\n     // Define  a private class for ListNode, which has val, prev, next\n     class ListNode {\n        int val;\n        List
\nclass FrontMiddleBackQueue {\n\n     // Define  a private class for ListNode, which has val, prev, next\n     class ListNode {\n        int val;\n        ListNode next;\n        ListNode prev;\n        ListNode(int val) {\n            this.val = val;     \n        }\n    }\n    \n\t// We should initilize the front and end ListNodes and maintain middle ListNode\n    int count;\n    ListNode middle;\n    ListNode front;\n    ListNode end;\n    \n    public FrontMiddleBackQueue() {\n        count = 0;\n        front = new ListNode(-1);\n        end = new ListNode(-1); \n        front.next = end;\n        end.prev = front;\n    }\n    \n    public void pushFront(int val) {\n        ListNode newNode = new ListNode(val);\n        newNode.prev = front;\n        newNode.next = front.next;\n        front.next.prev = newNode;\n        front.next = newNode;\n        count++;\n        if(count == 1) {\n            middle = newNode;\n        }else if(count % 2 == 0) {\n            middle = middle.prev;\n        }\n    }\n    \n    public void pushMiddle(int val) {\n        ListNode newNode = new ListNode(val);\n        if(count == 0) {\n            newNode.prev = front;\n            newNode.next = end;\n            end.prev = newNode;\n            front.next = newNode;\n            middle = newNode;\n            count++;\n            return;\n        }else if(count % 2 == 0) {\n           newNode.next = middle.next;\n           newNode.prev = middle;\n           middle.next.prev = newNode;\n           middle.next = newNode;\n           middle = newNode; \n        } else {\n           newNode.prev = middle.prev;\n           newNode.next = middle; \n           middle.prev.next = newNode;\n           middle.prev = newNode;\n           middle = newNode;  \n        }\n        count++;\n        return;\n    }\n    \n    \n    public void pushBack(int val) {\n        ListNode newNode = new ListNode(val);\n        newNode.prev = end.prev;\n        newNode.next = end;\n        end.prev.next = newNode;\n        end.prev = newNode;\n        count++;\n        if(count == 1) {\n            middle = newNode;\n        }else if(count % 2 != 0) {\n            middle = middle.next;\n        }\n    }\n    \n    public int popFront() {\n        if(count == 0) {\n            return -1;\n        }\n        int res =  front.next.val;     \n        removeNode(front.next);\n        count--;\n        if(count % 2 != 0) {\n            middle = middle.next;\n        } \n        return res;\n    }\n    \n    public int popMiddle() {\n        if(count == 0) {\n            return -1;\n        }\n        int res = middle.val;\n        if(count % 2 != 0) {\n            removeNode(middle);\n            middle = middle.prev;\n        } else {\n            removeNode(middle);\n            middle = middle.next;\n        }\n        count--;\n        return res;\n    }\n    \n    public int popBack() {\n        if(count > 0) {\n            int res =  end.prev.val;  \n            removeNode(end.prev); \n            count--;\n            if(count % 2 == 0) {\n                middle = middle.prev;\n            } \n            return res; \n        }\n        return -1;\n    }\n    \n    public void removeNode(ListNode l) {\n        l.next.prev = l.prev;\n        l.prev.next = l.next;\n    }\n}\n\n/**\n * Your FrontMiddleBackQueue object will be instantiated and called as such:\n * FrontMiddleBackQueue obj = new FrontMiddleBackQueue();\n * obj.pushFront(val);\n * obj.pushMiddle(val);\n * obj.pushBack(val);\n * int param_4 = obj.popFront();\n * int param_5 = obj.popMiddle();\n * int param_6 = obj.popBack();\n */
[]