Word Search in Trie in DSA Typescript - Time & Space Complexity
We want to understand how long it takes to find a word in a Trie data structure.
The question is: how does the search time grow as the word length changes?
Analyze the time complexity of the following code snippet.
class TrieNode {
children: Map = new Map();
isEndOfWord: boolean = false;
}
function searchWord(root: TrieNode, word: string): boolean {
let current = root;
for (const char of word) {
if (!current.children.has(char)) return false;
current = current.children.get(char)!;
}
return current.isEndOfWord;
}
This code checks if a given word exists in the Trie by following each character step-by-step.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Looping through each character of the word.
- How many times: Exactly once per character in the word.
Each additional character in the word adds one more step to check.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 checks |
| 100 | 100 checks |
| 1000 | 1000 checks |
Pattern observation: The number of steps grows directly with the word length.
Time Complexity: O(n)
This means the search time grows linearly with the length of the word you are searching for.
[X] Wrong: "Searching a word in a Trie takes constant time because it's a tree."
[OK] Correct: The search depends on the word length, so longer words take more steps, not always constant time.
Understanding this helps you explain why Tries are efficient for prefix searches and how their search time depends on word length, a common topic in interviews.
"What if the Trie stored words with only lowercase letters, and we used an array instead of a Map for children? How would the time complexity change?"
Practice
Trie data structure in word search problems?Solution
Step 1: Understand the Trie structure
A Trie stores characters in a tree where each path represents a prefix of words.Step 2: Identify the use in word search
This structure allows quick prefix-based search, making it efficient for word search problems.Final Answer:
To efficiently store and search words by their prefixes -> Option AQuick Check:
Trie = prefix search [OK]
- Confusing Trie with sorting structures
- Thinking Trie stores words linearly
- Assuming Trie performs arithmetic
Solution
Step 1: Check children type
Children should be a Map from string to TrieNode for efficient character mapping.Step 2: Check isEndOfWord type and initialization
It should be a boolean initialized to false to mark word endings correctly.Final Answer:
class TrieNode { children: Map; isEndOfWord: boolean; constructor() { this.children = new Map(); this.isEndOfWord = false; } } -> Option AQuick Check:
Correct types and initialization [OK]
- Using array instead of Map for children
- Using wrong types for isEndOfWord
- Initializing isEndOfWord incorrectly
class TrieNode {
children = new Map();
isEndOfWord = false;
}
class Trie {
root = new TrieNode();
insert(word: string) {
let node = this.root;
for (const ch of word) {
if (!node.children.has(ch)) {
node.children.set(ch, new TrieNode());
}
node = node.children.get(ch)!;
}
node.isEndOfWord = true;
}
search(word: string): boolean {
let node = this.root;
for (const ch of word) {
if (!node.children.has(ch)) return false;
node = node.children.get(ch)!;
}
return node.isEndOfWord;
}
}
const trie = new Trie();
trie.insert("car");
trie.insert("cap");
console.log(trie.search("cat"));Solution
Step 1: Trace insertion of "car" and "cap"
Both words create nodes for 'c', 'a', then diverge at 'r' and 'p' respectively, marking those ends as true.Step 2: Trace search for "cat"
Search finds 'c' and 'a', but 't' is not a child of 'a', so search returns false.Final Answer:
false -> Option BQuick Check:
Word not inserted = false [OK]
- Assuming partial prefix means true
- Confusing isEndOfWord with node existence
- Expecting undefined instead of false
search(word: string): boolean {
let node = this.root;
for (const ch of word) {
if (!node.children.has(ch)) return false;
node = node.children.get(ch)!;
}
return node.isEndOfWord === false;
}Solution
Step 1: Analyze the return statement
The method returns node.isEndOfWord === false, which means it returns true if the word is NOT ending here.Step 2: Correct the return logic
It should return node.isEndOfWord to confirm the word ends at this node.Final Answer:
The return condition should be node.isEndOfWord, not its negation -> Option DQuick Check:
Return true if word ends here [OK]
- Returning negation of isEndOfWord
- Changing loop direction unnecessarily
- Using wrong data structure for children
Solution
Step 1: Traverse Trie to prefix node
Follow characters of prefix to reach the node representing last prefix character.Step 2: Use backtracking from prefix node
Recursively explore all children nodes to collect complete words starting with prefix.Final Answer:
Traverse Trie nodes for prefix, then recursively collect words from that node using backtracking -> Option CQuick Check:
Prefix traversal + backtracking = Traverse Trie nodes for prefix, then recursively collect words from that node using backtracking [OK]
- Checking all words instead of prefix traversal
- Filtering array instead of Trie traversal
- Using hash map without Trie structure
Ready to prove it?
Pass the test and this pattern moves unknown
