Trie vs Hash Map for Prefix Matching in DSA C - Complexity Comparison
We want to understand how fast prefix matching works using two common data structures: Trie and Hash Map.
Which one handles searching prefixes more efficiently as the input grows?
Analyze the time complexity of the following Trie prefix search code snippet.
// Search prefix in Trie
bool searchPrefix(TrieNode* root, const char* prefix) {
TrieNode* node = root;
for (int i = 0; prefix[i] != '\0'; i++) {
int index = prefix[i] - 'a';
if (!node->children[index]) return false;
node = node->children[index];
}
return true;
}
This code checks if a prefix exists in a Trie by following nodes for each character.
Look for loops or repeated steps that affect time.
- Primary operation: Loop over each character in the prefix.
- How many times: Exactly once per character in the prefix (length m).
As the prefix length grows, the number of steps grows linearly.
| Input Size (prefix length m) | Approx. Operations |
|---|---|
| 10 | 10 steps |
| 100 | 100 steps |
| 1000 | 1000 steps |
Pattern observation: The time grows directly with prefix length, not with total words stored.
Time Complexity: O(m)
This means searching a prefix takes time proportional to the prefix length, independent of total words.
[X] Wrong: "Searching a prefix in a Trie depends on the number of words stored."
[OK] Correct: The search only follows nodes for prefix characters, so it depends on prefix length, not total words.
Understanding how Trie and Hash Map handle prefix search helps you choose the right tool for fast lookups in real problems.
What if we used a Hash Map storing all prefixes as keys? How would the time complexity for prefix search change?
Practice
Solution
Step 1: Understand prefix matching requirement
Prefix matching means finding all strings starting with a given prefix quickly.Step 2: Compare Trie and Hash Map for prefix search
Trie stores characters in nodes along paths, enabling fast prefix traversal. Hash Map is good for exact key lookup but not efficient for prefix search.Final Answer:
Trie, because it stores characters in a tree structure allowing fast prefix search -> Option AQuick Check:
Prefix search = Trie [OK]
- Thinking Hash Map supports prefix search efficiently
- Confusing array or stack with prefix matching
- Assuming Hash Map stores substrings as keys
Solution
Step 1: Understand Trie node children indexing
Children array is indexed by character offset from 'a', so use word[i] - 'a'.Step 2: Use correct pointer syntax in C
Since node is a pointer, use '->' to access children array.Final Answer:
node->children[word[i] - 'a'] = createNode(); -> Option AQuick Check:
Pointer access + char offset = node->children[word[i] - 'a'] = createNode(); [OK]
- Using dot instead of arrow for pointer
- Not subtracting 'a' from character
- Using character directly as index
TrieNode* root = createNode();
insert(root, "apple");
insert(root, "app");
insert(root, "bat");
printf("%d", startsWith(root, "app"));
printf("%d", startsWith(root, "bat"));
printf("%d", startsWith(root, "cat"));
Assume startsWith returns 1 if prefix exists, else 0.Solution
Step 1: Analyze inserted words and prefixes
Words inserted: "apple", "app", "bat". Prefixes checked: "app", "bat", "cat".Step 2: Check prefix existence
"app" is prefix of "apple" and "app" -> returns 1. "bat" is inserted word -> returns 1. "cat" not inserted -> returns 0.Final Answer:
110 -> Option BQuick Check:
Prefix found = 1,1,0 [OK]
- Assuming startsWith returns count instead of boolean
- Confusing prefix with exact match
- Ignoring that 'cat' was not inserted
int startsWith(TrieNode* root, char* prefix) {
TrieNode* node = root;
for (int i = 0; prefix[i]; i++) {
if (node->children[prefix[i]] == NULL) {
return 0;
}
node = node->children[prefix[i]];
}
return 1;
}Solution
Step 1: Identify children array indexing
Children array is indexed by character offset from 'a', so must use prefix[i] - 'a'.Step 2: Explain impact of wrong indexing
Using prefix[i] directly accesses out-of-bound indices, causing NULL always and returning 0.Final Answer:
Indexing children array without subtracting 'a' from prefix[i] -> Option CQuick Check:
Correct indexing = prefix[i] - 'a' [OK]
- Forgetting to subtract 'a' from character
- Not checking for NULL root
- Confusing loop condition with indexing
- Use a Trie to store all words and traverse nodes for prefix queries.
- Use a Hash Map storing all prefixes as keys with lists of words as values.
Solution
Step 1: Compare memory usage of Trie vs Hash Map for prefixes
Trie stores characters in shared nodes, avoiding duplicate prefix storage. Hash Map stores every prefix explicitly, causing large memory use.Step 2: Compare prefix query speed and scalability
Trie allows fast traversal by characters without storing all prefixes. Hash Map lookup is fast but building and storing all prefixes is expensive and slow.Final Answer:
Trie, because it uses less memory and supports fast prefix traversal -> Option DQuick Check:
Memory efficient prefix search = Trie [OK]
- Assuming Hash Map uses less memory for prefixes
- Thinking Trie stores all prefixes as separate keys
- Ignoring scalability for millions of words
Ready to prove it?
Pass the test and this pattern moves unknown
