Implement Trie (Prefix Tree)
MEDIUMDescription
A trie (pronounced as "try") or prefix tree is a tree data structure used to efficiently store and retrieve keys in a dataset of strings. There are various applications of this data structure, such as autocomplete and spellchecker.
Implement the Trie class:
Trie()Initializes the trie object.void insert(String word)Inserts the stringwordinto the trie.boolean search(String word)Returnstrueif the stringwordis in the trie (i.e., was inserted before), andfalseotherwise.boolean startsWith(String prefix)Returnstrueif there is a previously inserted stringwordthat has the prefixprefix, andfalseotherwise.
Example 1:
Input
["Trie", "insert", "search", "search", "startsWith", "insert", "search"]
[[], ["apple"], ["apple"], ["app"], ["app"], ["app"], ["app"]]
Output
[null, null, true, false, true, null, true]
Explanation
Trie trie = new Trie();
trie.insert("apple");
trie.search("apple"); // return True
trie.search("app"); // return False
trie.startsWith("app"); // return True
trie.insert("app");
trie.search("app"); // return True
Constraints:
1 <= word.length, prefix.length <= 2000wordandprefixconsist only of lowercase English letters.- At most
3 * 104calls in total will be made toinsert,search, andstartsWith.
Approaches
Checkout 2 different approaches to solve Implement Trie (Prefix Tree). Click on different approaches to view the approach and algorithm in detail.
Array-based Approach
This approach uses a simple array to store characters and implements a basic trie structure. Each node in the trie contains a boolean flag to mark the end of a word and an array of size 26 (for lowercase English letters) to store child nodes.
Algorithm
- Create a TrieNode class with an array of size 26 for children and a boolean flag
- For insert:
- Start from root
- For each character, create a new node if it doesn't exist
- Mark the last node as end of word
- For search:
- Traverse the trie following the characters
- Return true if last node exists and is marked as end of word
- For startsWith:
- Similar to search but only check if path exists
In this approach, we create a TrieNode class that contains:
- A boolean flag
isEndOfWordto mark if the node represents the end of a word - An array of TrieNode references of size 26 for each possible lowercase letter
Here's the implementation:
class TrieNode {
TrieNode[] children;
boolean isEndOfWord;
public TrieNode() {
children = new TrieNode[26];
isEndOfWord = false;
}
}
class Trie {
private TrieNode root;
public Trie() {
root = new TrieNode();
}
public void insert(String word) {
TrieNode current = root;
for(char ch : word.toCharArray()) {
int index = ch - 'a';
if(current.children[index] == null) {
current.children[index] = new TrieNode();
}
current = current.children[index];
}
current.isEndOfWord = true;
}
public boolean search(String word) {
TrieNode node = searchNode(word);
return node != null && node.isEndOfWord;
}
public boolean startsWith(String prefix) {
return searchNode(prefix) != null;
}
private TrieNode searchNode(String str) {
TrieNode current = root;
for(char ch : str.toCharArray()) {
int index = ch - 'a';
if(current.children[index] == null) {
return null;
}
current = current.children[index];
}
return current;
}
}
Complexity Analysis
Pros and Cons
- Simple implementation with array indexing
- Constant time lookup for children (array access)
- Memory efficient for small alphabets
- Fixed size array wastes space for sparse nodes
- Not flexible for different character sets
- Memory intensive for large character sets
Code Solutions
Checking out 5 solutions in different languages for Implement Trie (Prefix Tree). Click on different languages to view the code.
public class Trie { bool isEnd ; Trie [] children = new Trie [ 26 ]; public Trie () { } public void Insert ( string word ) { Trie node = this ; foreach ( var c in word ) { var idx = c - 'a' ; node . children [ idx ] ??= new Trie (); node = node . children [ idx ]; } node . isEnd = true ; } public bool Search ( string word ) { Trie node = SearchPrefix ( word ); return node != null && node . isEnd ; } public bool StartsWith ( string prefix ) { Trie node = SearchPrefix ( prefix ); return node != null ; } private Trie SearchPrefix ( string s ) { Trie node = this ; foreach ( var c in s ) { var idx = c - 'a' ; if ( node . children [ idx ] == null ) { return null ; } node = node . children [ idx ]; } return node ; } } /** * Your Trie object will be instantiated and called as such: * Trie obj = new Trie(); * obj.Insert(word); * bool param_2 = obj.Search(word); * bool param_3 = obj.StartsWith(prefix); */Video Solution
Watch the video walkthrough for Implement Trie (Prefix Tree)
Similar Questions
5 related questions you might find useful
Patterns:
Data Structures:
Companies:
Subscribe to Scale Engineer newsletter
Learn about System Design, Software Engineering, and interview experiences every week.
No spam, unsubscribe at any time.