Prefix Search Using Trie in DSA Go - Time & Space Complexity
We want to understand how fast we can find words that start with a given prefix using a Trie.
The question is: How does the search time grow as the prefix length or number of words changes?
Analyze the time complexity of the following code snippet.
// SearchPrefix returns true if prefix exists in Trie
func (t *Trie) SearchPrefix(prefix string) bool {
node := t.root
for _, ch := range prefix {
if node.children[ch] == nil {
return false
}
node = node.children[ch]
}
return true
}
This code checks if a given prefix exists by walking down the Trie nodes for each character.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Loop over each character in the prefix string.
- How many times: Exactly once per character in the prefix (length m).
As the prefix length grows, the search checks more nodes one by one.
| Input Size (prefix length m) | Approx. Operations |
|---|---|
| 10 | 10 checks |
| 100 | 100 checks |
| 1000 | 1000 checks |
Pattern observation: The operations grow linearly with prefix length.
Time Complexity: O(m)
This means the search time grows directly with the length of the prefix, not the number of words stored.
[X] Wrong: "The search time depends on the total number of words in the Trie."
[OK] Correct: The search only follows the prefix characters, so it depends on prefix length, not total words.
Knowing this helps you explain why Tries are efficient for prefix searches, a common real-world problem like autocomplete.
"What if the Trie stored words with very long alphabets (like Unicode)? How would that affect the time complexity?"
Practice
Trie data structure in prefix search?Solution
Step 1: Understand what prefix search means
Prefix search means finding all words that begin with a certain starting sequence of letters.Step 2: Understand Trie's role in prefix search
A Trie stores words in a tree-like structure where each node represents a character, making it fast to find all words sharing a prefix.Final Answer:
To efficiently find all words that start with a given prefix -> Option BQuick Check:
Prefix search = efficient word lookup [OK]
- Confusing Trie with sorting data structures
- Thinking Trie is for arithmetic operations
- Assuming Trie stores numbers only
Solution
Step 1: Identify the Trie node components
A Trie node should have a map from characters (rune) to child nodes and a boolean to mark word end.Step 2: Match the correct Go struct syntax
type TrieNode struct { children map[rune]*TrieNode; isEnd bool } uses a map[rune]*TrieNode and a bool isEnd, which fits the Trie node definition.Final Answer:
type TrieNode struct { children map[rune]*TrieNode; isEnd bool } -> Option DQuick Check:
Trie node = map + bool [OK]
- Using slice of int instead of map for children
- Confusing linked list node with Trie node
- Using int instead of bool for isEnd
trie := NewTrie()
trie.Insert("apple")
trie.Insert("app")
trie.Insert("application")
result := trie.StartsWith("app")
fmt.Println(result)
What will be the output of fmt.Println(result)?Solution
Step 1: Insert words into the Trie
Words "apple", "app", and "application" are inserted, all starting with prefix "app".Step 2: Search for prefix "app"
The StartsWith method returns all words starting with "app", which includes all three inserted words.Final Answer:
[apple app application] -> Option CQuick Check:
All words with prefix "app" = [apple app application] [OK]
- Missing the exact prefix word "app" in results
- Returning only one matching word
- Returning empty list if prefix matches
func (t *Trie) StartsWith(prefix string) []string {
node := t.root
for _, ch := range prefix {
if node.children[ch] == nil {
return nil
}
node = node.children[ch]
}
return node.words
}
What is the main bug causing incorrect prefix search results?Solution
Step 1: Analyze the prefix traversal loop
The loop correctly moves node down the Trie for each character in prefix.Step 2: Check the return statement after traversal
Returning node.words assumes all words under prefix are stored there, but usually words are stored in leaf nodes, so it misses collecting all words under subtree.Final Answer:
The code does not collect all words under the prefix node -> Option AQuick Check:
Prefix search must gather all subtree words [OK]
- Returning nil instead of empty slice is minor, not main bug
- Assuming words stored only at prefix node
- Ignoring recursive collection of words
Solution
Step 1: Understand the requirement
We want all words starting with prefix but exclude the word exactly equal to prefix.Step 2: Modify search result filtering
After collecting all words under prefix node, filter out the word that matches prefix exactly before returning.Final Answer:
After finding prefix node, return all words except the one equal to prefix -> Option AQuick Check:
Filter out exact prefix word from results [OK]
- Removing isEnd flag breaks normal word insertion
- Returning only longer words by length may miss valid words
- Returning prefix itself defeats the requirement
Ready to prove it?
Pass the test and this pattern moves unknown
