Autocomplete System with Trie in DSA Java - Time & Space Complexity
We want to understand how fast the autocomplete system works as we add more words or search for prefixes.
Specifically, how does the time to find suggestions grow when the input size changes?
Analyze the time complexity of the following code snippet.
class TrieNode {
TrieNode[] children = new TrieNode[26];
boolean isWord = false;
}
void insert(TrieNode root, String word) {
TrieNode node = root;
for (char c : word.toCharArray()) {
int index = c - 'a';
if (node.children[index] == null) {
node.children[index] = new TrieNode();
}
node = node.children[index];
}
node.isWord = true;
}
This code inserts a word into a Trie, letter by letter, creating nodes as needed.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Looping through each character of the input word.
- How many times: Once for each letter in the word (length n).
As the word length grows, the number of steps grows directly with it.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 steps |
| 100 | About 100 steps |
| 1000 | About 1000 steps |
Pattern observation: The time grows linearly with the length of the word.
Time Complexity: O(n)
This means the time to insert a word grows directly with the word's length.
[X] Wrong: "The time depends on the total number of words already in the Trie."
[OK] Correct: Insertion only depends on the length of the word being added, not how many words are stored.
Understanding this helps you explain how tries efficiently handle prefix searches and insertions, a common real-world problem.
"What if we changed the Trie to store words with uppercase letters and digits? How would the time complexity change?"
Practice
Trie in an autocomplete system?Solution
Step 1: Understand the role of Trie in prefix search
A Trie is a tree-like data structure that stores characters of words in a way that common prefixes share nodes.Step 2: Connect Trie usage to autocomplete
Autocomplete requires quick lookup of words starting with a given prefix, which Trie supports efficiently.Final Answer:
To efficiently store and search prefixes of words -> Option BQuick Check:
Trie = prefix search [OK]
- Confusing Trie with sorting data structure
- Thinking Trie encrypts data
- Assuming Trie counts word frequency only
Solution
Step 1: Identify the correct data type for children nodes
Each child should be a reference to another TrieNode, so an array of TrieNode objects is needed.Step 2: Check other options for correctness
Options B, C, and D use primitive types or String arrays which cannot represent child nodes properly.Final Answer:
class TrieNode { TrieNode[] children = new TrieNode[26]; boolean isWord; } -> Option DQuick Check:
Children = TrieNode array [OK]
- Using int or char arrays instead of TrieNode array
- Using String array for children
- Forgetting to initialize children array
Trie trie = new Trie();
trie.insert("dog");
trie.insert("deer");
trie.insert("deal");
List<String> results = trie.autocomplete("de");
System.out.println(results);Solution
Step 1: Understand inserted words and prefix search
Words inserted are "dog", "deer", and "deal". The prefix searched is "de".Step 2: Filter words starting with prefix "de"
Only "deer" and "deal" start with "de"; "dog" starts with "do".Final Answer:
["deer", "deal"] -> Option AQuick Check:
Autocomplete("de") = ["deer", "deal"] [OK]
- Including words not matching prefix
- Returning empty list by mistake
- Confusing prefix "de" with "do"
public void insert(String word) {
TrieNode node = root;
for (int i = 0; i <= word.length(); i++) {
char c = word.charAt(i);
int index = c - 'a';
if (node.children[index] == null) {
node.children[index] = new TrieNode();
}
node = node.children[index];
}
node.isWord = true;
}Solution
Step 1: Analyze loop boundary
The loop runs from i = 0 to i <= word.length(), which causes i to reach word.length(), an invalid index for charAt.Step 2: Fix loop condition
Changing condition to i < word.length() prevents IndexOutOfBoundsException by stopping before invalid index.Final Answer:
Change loop condition to i < word.length() to avoid IndexOutOfBoundsException -> Option AQuick Check:
Loop index < word.length() [OK]
- Using <= instead of < in loop condition
- Ignoring IndexOutOfBoundsException
- Misunderstanding charAt indexing
Solution
Step 1: Understand frequency tracking in Trie nodes
Storing frequency count at each word node allows tracking how often each word is used.Step 2: Use priority queue to get top frequent words during autocomplete
During prefix search, a priority queue can efficiently retrieve words with highest frequency.Final Answer:
Store a frequency count at each word node and use a priority queue during search -> Option CQuick Check:
Frequency + priority queue = efficient sorted suggestions [OK]
- Sorting all words after each insertion (inefficient)
- Separating frequency from Trie nodes (loses prefix efficiency)
- Using linked list for sorting (slow access)
Ready to prove it?
Pass the test and this pattern moves unknown
