3 pointers, all O(1) operations.
\n1.  If we ignore the pushMid and popMid operations, this would be a straightforward Doubly Linked List. I implemented that first. \n2.  Maintaind a fake head 
\n1.  If we ignore the **pushMid** and **popMid** operations, this would be a straightforward Doubly Linked List. I implemented that first. \n2.  Maintaind a fake head and tail, that are outside the extereme ends of the actual list. This reduces the number of null check cases I needed to handle.\n3. In order to accomodate mid, I realised that mid only changes by one position depending on the size of the list is even or odd. Once I listed down the conditions, I incorporated those cases in the pushFront, popFront, pushBack and popBack methods.\n\n```\nclass FrontMiddleBackQueue {\n\n        LinkedListNode head, tail, mid;\n\n        int listSize;\n\n        public FrontMiddleBackQueue() {\n            listSize = 0;\n            head = new LinkedListNode(-1);\n            tail = new LinkedListNode(-1);\n            head.next = tail;\n            tail.prev = head;\n        }\n\n        public void pushFront(int val) {\n            LinkedListNode node = new LinkedListNode(val);\n            if (head.next == tail) {\n\t\t\t// This is the first element, so now is a good time to initialize the mid pointer.\n                mid = node;\n                mid.prev = head;\n                mid.next = tail;\n                head.next = mid;\n                tail.prev = mid;\n                listSize++;\n                return;\n            }\n            node.next = head.next;\n            head.next.prev = node;\n            node.prev = head;\n            head.next = node;\n            listSize++;\n            if (listSize % 2 == 0) {\n                mid = mid.prev;\n            }\n        }\n\n        public void pushMiddle(int val) {\n            LinkedListNode node = new LinkedListNode(val);\n\n            if (head.next == tail) {\n                mid = node;\n                mid.prev = head;\n                mid.next = tail;\n                head.next = mid;\n                tail.prev = mid;\n                listSize++;\n                return;\n            }\n\n            if (listSize % 2 == 1) {\n                node.prev = mid.prev;\n                node.next = mid;\n                node.prev.next = node;\n                node.next.prev = node;\n            } else {\n                node.next = mid.next;\n                mid.next.prev = node;\n                node.prev = mid;\n                mid.next = node;\n            }\n            mid = node;\n            listSize++;\n        }\n\n        public void pushBack(int val) {\n            LinkedListNode node = new LinkedListNode(val);\n            if (head.next == tail) {\n                mid = node;\n                mid.prev = head;\n                mid.next = tail;\n                head.next = mid;\n                tail.prev = mid;\n                listSize++;\n                return;\n            }\n            node.prev = tail.prev;\n            tail.prev.next = node;\n            node.next = tail;\n            tail.prev = node;\n            listSize++;\n            if (listSize % 2 == 1) {\n                mid = mid.next;\n            }\n        }\n\n        public int popFront() {\n            if (head.next == tail) {\n                return -1;\n            } else {\n                LinkedListNode node = head.next;\n                node.next.prev = head;\n                head.next = node.next;\n                listSize--;\n                if(listSize % 2 == 1) {\n                    mid = mid.next;\n                }\n                return node.val;\n            }\n        }\n\n        public int popMiddle() {\n            if (head.next == tail) {\n                return -1;\n            } else {\n                LinkedListNode node = mid;\n                node.next.prev = node.prev;\n                node.prev.next = node.next;\n                if (listSize % 2 == 1) {\n                    mid = mid.prev;\n                } else {\n                    mid = mid.next;\n                }\n                listSize--;\n                return node.val;\n            }\n        }\n\n        public int popBack() {\n            if (head.next == tail) {\n                return -1;\n            } else {\n                LinkedListNode node = tail.prev;\n                node.prev.next = tail;\n                tail.prev = node.prev;\n                listSize--;\n                if(listSize % 2 == 0) {\n                    mid = mid.prev;\n                }\n                return node.val;\n            }\n        }\n    }\n\n    class LinkedListNode {\n        int val;\n        LinkedListNode next;\n        LinkedListNode prev;\n\n        public LinkedListNode(int val) {\n            this.val = val;\n        }\n    }\n```
['Two Pointers']