745 - Prefix and Suffix Search
Difficulty: Hard | Pattern: Trie / HashMap | Company tags: Google, Amazon
Problem Statement
Design a special dictionary that searches the words in it by a prefix and a suffix.
Implement the WordFilter class:
WordFilter(String[] words)Initializes the object with thewordsin the dictionary.f(String pref, String suff)Returns the index of the word in the dictionary, which has the prefixprefand the suffixsuff. If there is more than one valid index, return the largest of them. If there is no such word in the dictionary, return-1.
Example:
WordFilter wf = new WordFilter(["apple"]);
wf.f("a", "e") → 0
wf.f("b", "") → -1
Approach: Precompute All (prefix, suffix) Pairs — O(n × L²), O(n × L²)
Key insight: For each word, generate all (prefix, suffix) pairs and store the word's index in a hashmap. For duplicate pairs, store the highest index.
class WordFilter:
def __init__(self, words: list[str]):
self.lookup = {}
for idx, word in enumerate(words):
n = len(word)
for i in range(n + 1): # prefix lengths 0..n
for j in range(n + 1): # suffix lengths 0..n
key = (word[:i], word[n-j:] if j > 0 else "")
self.lookup[key] = idx
def f(self, pref: str, suff: str) -> int:
return self.lookup.get((pref, suff), -1)
Alternative: Joined Key Trick — O(n × L²) build, O(1) query
Encode each (prefix, suffix) pair as prefix + "#" + suffix string — faster in practice.
class WordFilter:
def __init__(self, words):
self.lookup = {}
for i, word in enumerate(words):
n = len(word)
for p in range(n + 1):
for s in range(n + 1):
key = word[:p] + '#' + word[n-s:]
self.lookup[key] = i
def f(self, pref, suff):
return self.lookup.get(pref + '#' + suff, -1)
Complexity
- Build Time: O(n × L²) where L = max word length
- Query Time: O(L) for string hashing
- Space: O(n × L²)
Trade-off
For large dictionaries and many queries, a Trie-based approach is more memory efficient. For interview, the hash map approach is simpler to implement correctly.