Implement a FIFO Queue Using Two Stacks
Company: Apple
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Onsite
Quick Answer: This question evaluates understanding of data structure design, specifically simulating queue (FIFO) behavior using only stack (LIFO) operations. It is commonly asked in coding interviews to assess amortized time complexity reasoning and the ability to translate between abstract data structure interfaces, testing practical algorithmic implementation skill.
Constraints
- 1 <= x <= 9
- At most 100 calls in total are made to push, pop, peek, and empty.
- pop and peek are only ever called on a non-empty queue.
- Only standard stack operations may be used, and the storage must be two stacks.
Examples
Input: (['MyQueue', 'push', 'push', 'peek', 'pop', 'empty'], [[], [1], [2], [], [], []])
Expected Output: [None, None, None, 1, 1, False]
Explanation: Push 1 then 2. peek() returns the front (1). pop() removes and returns 1. The queue still holds 2, so empty() is False.
Input: (['MyQueue', 'push', 'pop', 'empty'], [[], [5], [], []])
Expected Output: [None, None, 5, True]
Explanation: Push 5, pop returns 5, and the queue is now empty so empty() is True.
Input: (['MyQueue', 'empty'], [[], []])
Expected Output: [None, True]
Explanation: A freshly constructed queue with no elements: empty() returns True.
Input: (['MyQueue', 'push', 'push', 'push', 'pop', 'push', 'peek', 'pop', 'pop', 'empty'], [[], [3], [7], [9], [], [4], [], [], [], []])
Expected Output: [None, None, None, None, 3, None, 7, 7, 9, False]
Explanation: Push 3,7,9; pop returns 3 (FIFO front). Push 4 (queue is now 7,9,4). peek returns 7, pop returns 7, pop returns 9. The queue holds only 4, so empty() is False. This interleaves pushes after a transfer to confirm ordering stays correct.
Hints
- Use two stacks: one for incoming pushes (in_stack) and one for outgoing pops/peeks (out_stack).
- Always push new elements onto in_stack. Only move elements to out_stack when out_stack is empty and you need to pop or peek.
- Transferring reverses the order once: the bottom of in_stack becomes the top of out_stack, which is exactly the front of the FIFO queue.
- The queue is empty only when BOTH stacks are empty. Each element is transferred at most once, giving amortized O(1) operations.