Queue Using Stacks
Turning LIFO into FIFO
Two stacks can implement a queue even though each stack by itself returns elements in reverse order. The idea is a double reversal: the first stack accepts new elements, and they are moved into the second stack for reading. After the transfer, the oldest element ends up on top of the second stack.
class QueueWithStacks {
private final Deque<Integer> input = new ArrayDeque<>();
private final Deque<Integer> output = new ArrayDeque<>();
void add(int value) {
input.push(value);
}
int remove() {
moveIfNeeded();
return output.pop();
}
private void moveIfNeeded() {
if (!output.isEmpty()) {
return;
}
while (!input.isEmpty()) {
output.push(input.pop());
}
}
}
Why we should not transfer after every insertion
As long as output contains elements, their order is already correct and does not need to change.
New values can accumulate in input. A transfer happens only when an element must be removed
and output is empty.
Amortized complexity
One particular remove() call may transfer many elements and take O(n) time.
But each element follows the path input → output only once during the queue's lifetime,
and is then removed once. Therefore a sequence of operations has an amortized cost of O(1) per operation.