Design a Prefix-Suggestion Search Interface
Charta HealthSoftware Engineer · OnsiteLast updated
Design and implement an in-memory prefix suggestion engine that indexes document titles, provides ranked auto-complete results, and prevents out-of-order race conditions from asynchronous search queries.
Problem Statement
You are tasked with building the core search-as-you-type engine for a medical records platform. The service must load a collection of document titles, support fast case-insensitive prefix lookups, rank results based on title popularity, and discard stale results caused by asynchronous or out-of-order network responses.
Implement the PrefixSearchEngine class with the following methods:
__init__(self, titles: list[tuple[str, int]]): Initializes the search engine with a list of(title, popularity)tuples. Each title is a non-empty string, and popularity is a positive integer (higher means more relevant).query(self, prefix: str, request_id: int, limit: int = 5) -> list[str] | None: Searches for up tolimittitles that start withprefix(case-insensitive). Results should be ranked primarily by descending popularity, and secondarily in lexicographical order (ascending) to break ties. If a query arrives with arequest_idthat is less than or equal to the highestrequest_idalready processed, the engine should treat it as a stale query and returnNone.
Matching rules:
- Matching must be case-insensitive, but returned titles must retain their original casing.
- Exact prefix match only: words must start with the given prefix string.
- If multiple identical titles exist, deduplicate them by retaining only the instance with the highest popularity.
Example
records = [
("Clinical Notes - Cardiology", 120),
("Clinical Summary", 95),
("clinical notes - neurology", 150),
("CBC Lab Results", 200),
("Chest X-Ray", 80),
]
engine = PrefixSearchEngine(records)
# Query 1: prefix "clin", request_id 1
engine.query("clin", request_id=1, limit=3)
# Output: ["clinical notes - neurology", "Clinical Notes - Cardiology", "Clinical Summary"]
# Query 2: prefix "c", request_id 3
engine.query("c", request_id=3, limit=2)
# Output: ["CBC Lab Results", "clinical notes - neurology"]
# Query 3: Stale response arrived late (request_id 2 <= 3)
engine.query("clinical", request_id=2, limit=5)
# Output: None
Constraints
- Total unique titles
N <= 50,000 - Average title length
<= 80characters - Query prefix length
<= 50characters request_idis a monotonically increasing integer (1 <= request_id <= 10^9)1 <= limit <= 50- Lookups should execute efficiently (e.g., Trie-based indexing or sorted prefix arrays).
Hints
Hint 1
Use a Trie where each node stores or points to the pre-sorted top candidate titles to achieve near-instant prefix retrieval without scanning the entire collection.
Hint 2
Track the maximum processed `request_id` in an instance variable to instantly discard out-of-order queries.
Hint 3
Normalize title strings to lowercase during insertion and querying for case-insensitive matching, while storing the original casing in the payload.
Follow-up questions
- How would you extend this design to support infix or multi-word prefix search (e.g., typing 'cardio' finds 'Clinical Notes - Cardiology')?
- If the document catalog updates dynamically with thousands of writes per minute, how would you balance read latency with thread-safe write updates?
- How would you adapt the stale response protection mechanism on the client side using Web APIs like `AbortController`?
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.