Build a Dynamic Exact-Suffix Search Index
AndurilSoftware Engineer · OnsiteLast updated
Design an in-memory index that supports dynamically inserting words and checking whether any previously inserted word ends with a given suffix in time proportional to the suffix length.
Dynamic Exact-Suffix Search Index
Design a data structure that maintains a dynamic collection of strings and supports efficient suffix lookups. The data structure must handle interleaved insertions and queries, where a query determines if any string currently in the collection ends with a specified exact, case-sensitive suffix.
Implement the SuffixIndex class:
SuffixIndex(): Initializes the index data structure.void insert(String word): Insertswordinto the collection.boolean has_suffix(String suffix): Returnstrueif at least one word inserted into the collection ends withsuffix, andfalseotherwise.
Interface
class SuffixIndex:
def __init__(self):
pass
def insert(self, word: str) -> None:
pass
def has_suffix(self, suffix: str) -> bool:
pass
Examples
index = SuffixIndex()
index.insert("surveillance")
index.insert("guidance")
index.insert("reconnaissance")
index.has_suffix("ance") # Returns True ("guidance", "reconnaissance")
index.has_suffix("lance") # Returns True ("surveillance")
index.has_suffix("surveil") # Returns False ("surveil" is a prefix, not a suffix)
index.has_suffix("e") # Returns True (all three words end in "e")
index.has_suffix("drone") # Returns False
Constraints
1 <= word.length, suffix.length <= 2,000wordandsuffixconsist of printable ASCII characters and are case-sensitive.- At most
100,000total calls toinsertandhas_suffixcombined. - Total length of all inserted words does not exceed
1,000,000characters.
Edge Cases
- A word is considered a suffix of itself (e.g., after inserting
"target",has_suffix("target")must returntrue). - Querying before any words are inserted should safely return
false. - Case sensitivity:
"Radar"does not match suffix"radar".
Hints
Hint 1
A standard Trie checks for string prefixes by traversing characters from left to right.
Hint 2
Consider what happens to suffixes if you reverse both the inserted words and the queried suffixes before traversing.
Hint 3
Unlike exact word matching, matching a suffix does not require the trie traversal to end on a terminal word marker—any valid path that consumes the entire reversed suffix proves that at least one word has that suffix.
Follow-up questions
- How would you extend the index to return the exact number of words ending with the given suffix?
- How would you support a `delete(word)` operation while cleaning up orphan nodes to save memory?
- If millions of long strings with high redundancy share suffixes, how would you compress linear node chains (e.g., using a radix/Patricia trie)?
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.