Two Stacks, One Queue: Implementing a Queue Using Two Stacks for Coding Interviews
Introduction
In coding interviews, you may be challenged to implement one data structure using another. For instance, a common question involves implementing a queue using two stacks. This may seem counterintuitive at first, as queues and stacks have different characteristics - a queue follows a First-In-First-Out (FIFO) pattern, while a stack follows a Last-In-First-Out (LIFO) pattern. However, with the clever use of two stacks, we can mimic a queue's behavior. This blog post will guide you through this process using Python.
Understanding Queues and Stacks
Before diving into the solution, let's quickly recap the basic principles of queues and stacks.
A queue is a linear data structure that follows a FIFO order for operations. This means that the first element added will be the first one to be removed. It has two main operations: enqueue
, which adds an element to the back of the queue, and dequeue
, which removes an element from the front.
A stack is a linear data structure that follows a LIFO order for operations. This means that the last element added will be the first one to be removed. It has two main operations: push
, which adds an element to the top of the stack, and pop
, which removes the topmost element.
Implementing a Queue using Two Stacks
To implement a queue using two stacks, we'll use one stack (stack1
) for enqueuing and another (stack2
) for dequeuing. Here's how it works:
- To
enqueue
an element, we simply push it ontostack1
. - To
dequeue
an element, we pop an element fromstack2
. Ifstack2
is empty, we first move all elements fromstack1
tostack2
, effectively reversing their order.
class Queue:
def __init__(self):
self.stack1 = []
self.stack2 = []
def enqueue(self, x):
self.stack1.append(x)
def dequeue(self):
if not self.stack2:
while self.stack1:
self.stack2.append(self.stack1.pop())
return self.stack2.pop()
This solution ensures that the oldest element (the first one inserted) is always at the top of stack2
, ready to be dequeued.
Testing the Queue Implementation
Now, let's test our queue implementation:
queue = Queue()
queue.enqueue('a')
queue.enqueue('b')
queue.enqueue('c')
print(queue.dequeue()) # Output: 'a'
queue.enqueue('d')
print(queue.dequeue()) # Output: 'b'
Conclusion
Although this problem may seem challenging initially, it provides an excellent way to demonstrate an understanding of basic data structures. Moreover, it highlights the power of data structures and how they can be manipulated to solve complex problems. As always, the key to mastering these concepts lies in practice. Happy coding!
P.S. Want weekly python coding challenges and news? Sign up for the newsletter to get them directly in your inbox: https://weeklypython.substack.com/welcome