Design a queue that supports push and pop operations in the front, middle, and back.
Implement the FrontMiddleBack class:
Notice that when there are two middle position choices, the operation is performed on the frontmost middle position choice. For example:
Example 1:
Input: ["FrontMiddleBackQueue", "pushFront", "pushBack", "pushMiddle", "pushMiddle", "popFront", "popMiddle", "popMiddle", "popBack", "popFront"] [[], [1], [2], [3], [4], [], [], [], [], []] Output: [null, null, null, null, null, 1, 3, 4, 2, -1] Explanation: FrontMiddleBackQueue q = new FrontMiddleBackQueue(); q.pushFront(1); // [1] q.pushBack(2); // [1, 2] q.pushMiddle(3); // [1, 3, 2] q.pushMiddle(4); // [1, 4, 3, 2] q.popFront(); // return 1 -> [4, 3, 2] q.popMiddle(); // return 3 -> [4, 2] q.popMiddle(); // return 4 -> [2] q.popBack(); // return 2 -> [] q.popFront(); // return -1 -> [] (The queue is empty)
Constraints:
class FrontMiddleBackQueue {
LinkedList<Integer> left, right;
int size;
public FrontMiddleBackQueue() {
left = new LinkedList<>();
right = new LinkedList<>();
size = 0;
}
public void pushFront(int val) {
left.addFirst(val);
if (left.size() > right.size()) {
right.addFirst(left.removeLast());
}
size++;
}
public void pushMiddle(int val) {
if (left.size() == right.size()) {
right.addFirst(val);
} else {
left.addLast(val);
}
size++;
}
public void pushBack(int val) {
if (left.size() < right.size()) {
left.addLast(right.removeFirst());
}
right.addLast(val);
size++;
}
public int popFront() {
if (size == 0) {
return -1;
}
if (left.size() < right.size()) {
left.addLast(right.removeFirst());
}
int val = left.removeFirst();
size--;
return val;
}
public int popMiddle() {
if (size == 0) {
return -1;
}
int val;
if (left.size() == right.size()) {
val = left.removeLast();
} else {
val = right.removeFirst();
}
size--;
return val;
}
public int popBack() {
if (size == 0) {
return -1;
}
int val = right.removeLast();
if (left.size() > right.size()) {
right.addFirst(left.removeLast());
}
size--;
return val;
}
}