Design a Linked Queue with Deletion Follow-Ups
AmazonSoftware Engineer · OnsiteLast updated
Implement a linked-list-based FIFO queue supporting constant-time core operations, extended with value-based deletion methods that correctly maintain queue integrity and pointer boundaries.
Problem Statement
Design a First-In-First-Out (FIFO) queue backed by a linked list. The queue must support standard queue operations in O(1) time, as well as extended deletion methods that remove elements by value while preserving the relative ordering of the remaining elements.
Implement the LinkedQueue class with the following methods:
enqueue(val: int) -> None: Insertsvalat the rear of the queue inO(1)time.dequeue() -> int: Removes and returns the value at the front of the queue inO(1)time. Raises anIndexErrorif the queue is empty.peek() -> int: Returns the value at the front without removing it. Raises anIndexErrorif the queue is empty.is_empty() -> bool: ReturnsTrueif the queue has no elements, otherwiseFalse.delete_first(val: int) -> bool: Searches from front to back and removes the first occurrence ofval. ReturnsTrueif an element was found and removed, orFalseifvaldoes not exist in the queue.delete_all(val: int) -> int: Removes all occurrences ofvalfrom the queue. Returns the total count of removed elements.
After any deletion, the queue's front (head), rear (tail), and size must remain consistent so subsequent enqueue and dequeue operations execute correctly.
Example
q = LinkedQueue()
q.enqueue(10)
q.enqueue(20)
q.enqueue(30)
q.enqueue(20)
print(q.delete_first(20)) # Output: True (removes first 20; queue is now 10 -> 30 -> 20)
print(q.peek()) # Output: 10
print(q.delete_all(20)) # Output: 1 (removes remaining 20; queue is now 10 -> 30)
print(q.dequeue()) # Output: 10
print(q.dequeue()) # Output: 30
print(q.is_empty()) # Output: True
Constraints
- At most
10^5total operations across all methods. - Node values are integers in the range
[-10^9, 10^9]. enqueue,dequeue,peek, andis_emptymust run inO(1)time.delete_firstanddelete_allmust run inO(n)time andO(1)auxiliary space, wherenis the current number of elements.
Hints
Hint 1
Maintain both `head` (front) and `tail` (rear) pointers to ensure `enqueue` and `dequeue` run in O(1) time.
Hint 2
When deleting a node, take special care if the target node is the `head`, the `tail`, or the only remaining node in the queue.
Hint 3
For `delete_all`, iterate through the list using a `prev` pointer (or a dummy node) and update `tail` whenever the deleted node was the last element.
Follow-up questions
- How would you redesign the data structure to support O(1) removal of an arbitrary node given a direct reference or unique key?
- How would you make this queue thread-safe for multi-producer and multi-consumer workloads without bottlenecking on a single global lock?
- What trade-offs arise if you implement deletion via lazy tombstone marking instead of immediate pointer manipulation?
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.