Solving Leetcode Interviews in Seconds with AI: Implement Queue using Stacks
Introduction
In this blog post, we will explore how to solve the LeetCode problem "232" using AI. LeetCode is a popular platform for preparing for coding interviews, and with the help of AI tools like Chatmagic, we can generate solutions quickly and efficiently - helping you pass the interviews and get the job offer without having to study for months.
Problem Statement
Implement a first in first out (FIFO) queue using only two stacks. The implemented queue should support all the functions of a normal queue (push, peek, pop, and empty). Implement the MyQueue class: void push(int x) Pushes element x to the back of the queue. int pop() Removes the element from the front of the queue and returns it. int peek() Returns the element at the front of the queue. boolean empty() Returns true if the queue is empty, false otherwise. Notes: You must use only standard operations of a stack, which means only push to top, peek/pop from top, size, and is empty operations are valid. Depending on your language, the stack may not be supported natively. You may simulate a stack using a list or deque (double-ended queue) as long as you use only a stack's standard operations. Example 1: Input ["MyQueue", "push", "push", "peek", "pop", "empty"] [[], [1], [2], [], [], []] Output [null, null, null, 1, 1, false] Explanation MyQueue myQueue = new MyQueue(); myQueue.push(1); // queue is: [1] myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue) myQueue.peek(); // return 1 myQueue.pop(); // return 1, queue is [2] myQueue.empty(); // return false Constraints: 1 <= x <= 9 At most 100 calls will be made to push, pop, peek, and empty. All the calls to pop and peek are valid. Follow-up: Can you implement the queue such that each operation is amortized O(1) time complexity? In other words, performing n operations will take overall O(n) time even if one of those operations may take longer.
Explanation
Here's an efficient implementation of a FIFO queue using two stacks, addressing the amortized O(1) time complexity requirement:
- Key Idea: Utilize two stacks:
stack1(for enqueue/push operations) andstack2(for dequeue/pop and peek operations). - Lazy Transfer: Only when
stack2is empty, transfer all elements fromstack1tostack2. This ensures the correct order for dequeuing. Amortized O(1): While transferring elements from
stack1tostack2takes O(n) time, it only happens whenstack2is empty. Subsequent pop and peek operations onstack2are O(1) untilstack2is empty again. Thus over a sequence of operations, the cost averages out to O(1) per operation.Runtime Complexity: Amortized O(1) for all operations. Storage Complexity: O(n) where n is the number of elements in the queue.
Code
class MyQueue:
def __init__(self):
self.stack1 = [] # Used for enqueue operations
self.stack2 = [] # Used for dequeue operations
def push(self, x: int) -> None:
self.stack1.append(x)
def pop(self) -> int:
if not self.stack2:
while self.stack1:
self.stack2.append(self.stack1.pop())
return self.stack2.pop()
def peek(self) -> int:
if not self.stack2:
while self.stack1:
self.stack2.append(self.stack1.pop())
return self.stack2[-1]
def empty(self) -> bool:
return not self.stack1 and not self.stack2