MediumBlind75StringTrieDesign
Implement Trie (Prefix Tree)
Implement a trie with insert, search, and startsWith methods.
Examples
Input
trie.insert('apple'); trie.search('apple'); trie.startsWith('app')Output
true, true
Insert 'apple', search finds it, startsWith('app') is true.
Input
trie.search('app')Output
false
'app' is not a complete word.
Constraints
- •
1 <= word.length, prefix.length <= 2000 - •
word and prefix consist only of lowercase English letters. - •
At most 3 * 10^4 calls will be made to insert, search, and startsWith.
Approaches
Use arrays to represent children for each node.
CodeT: O(m) per operation | S: O(m)
class TrieNode:
def __init__(self):
self.children = [None] * 26
self.is_end = False
class Trie:
def __init__(self):
self.root = TrieNode()
def insert(self, word):
node = self.root
for char in word:
idx = ord(char) - ord('a')
if not node.children[idx]:
node.children[idx] = TrieNode()
node = node.children[idx]
node.is_end = True
def search(self, word):
node = self.root
for char in word:
idx = ord(char) - ord('a')
if not node.children[idx]:
return False
node = node.children[idx]
return node.is_end
def startsWith(self, prefix):
node = self.root
for char in prefix:
idx = ord(char) - ord('a')
if not node.children[idx]:
return False
node = node.children[idx]
return TrueUse dictionaries for flexible character mapping.
CodeT: O(m) per operation | S: O(m)
class TrieNode:
def __init__(self):
self.children = {}
self.is_end = False
class Trie:
def __init__(self):
self.root = TrieNode()
def insert(self, word):
node = self.root
for char in word:
if char not in node.children:
node.children[char] = TrieNode()
node = node.children[char]
node.is_end = True
def search(self, word):
node = self.root
for char in word:
if char not in node.children:
return False
node = node.children[char]
return node.is_end
def startsWith(self, prefix):
node = self.root
for char in prefix:
if char not in node.children:
return False
node = node.children[char]
return TrueSame hash map approach with cleaner code.
Diagram
insert('apple'):
root->a->p->p->l->e(is_end)
search('apple'): traverse to e, is_end=True -> True
startsWith('app'): traverse to p -> True
search('app'): traverse to p, is_end=False -> False
CodeT: O(m) per operation | S: O(m)
class TrieNode:
def __init__(self):
self.children = {}
self.is_end = False
class Trie:
def __init__(self):
self.root = TrieNode()
def insert(self, word):
node = self.root
for c in word:
node = node.children.setdefault(c, TrieNode())
node.is_end = True
def search(self, word):
node = self._find(word)
return node is not None and node.is_end
def startsWith(self, prefix):
return self._find(prefix) is not None
def _find(self, prefix):
node = self.root
for c in prefix:
if c not in node.children:
return None
node = node.children[c]
return nodeComplexity Comparison
| Approach | Time | Space | Description |
|---|---|---|---|
| Array-Based Trie | O(m) per operation | O(m) | Use arrays to represent children for each node. |
| Hash Map-Based Trie | O(m) per operation | O(m) | Use dictionaries for flexible character mapping. |
| Optimized Trie | O(m) per operation | O(m) | Same hash map approach with cleaner code. |
Array-Based Trie
T: O(m) per operationS: O(m)
Use arrays to represent children for each node.
Hash Map-Based Trie
T: O(m) per operationS: O(m)
Use dictionaries for flexible character mapping.
Optimized Trie
T: O(m) per operationS: O(m)
Same hash map approach with cleaner code.
Common Mistakes
Not marking the end of a complete word
Using a fixed-size array when the character set is unknown
Not handling the case where a prefix is a complete word