What if you could find any word instantly without flipping through pages?
Why Word Search in Trie in DSA C++?
Imagine you have a huge dictionary of words written on paper. You want to find if a word exists, but you have to flip through every page and every word one by one.
This manual search is very slow and tiring. It wastes time flipping pages and checking words, and you might miss the word or make mistakes.
A Trie is like a smart tree that organizes words by their letters. It lets you quickly jump to the right place for each letter, so you find words fast without checking everything.
bool searchWord(vector<string> dictionary, string word) {
for (string w : dictionary) {
if (w == word) return true;
}
return false;
}bool searchWord(TrieNode* root, string word) {
TrieNode* current = root;
for (char c : word) {
if (!current->children[c - 'a']) return false;
current = current->children[c - 'a'];
}
return current->isEndOfWord;
}It enables lightning-fast word searches even in huge word lists, making text processing and autocomplete smooth and efficient.
When you type on your phone keyboard, the system quickly checks possible words to suggest completions or corrections using a Trie behind the scenes.
Manual word search is slow and error-prone.
Trie organizes words by letters for fast lookup.
Using Trie makes word search efficient and scalable.
Practice
Trie data structure in word search problems?Solution
Step 1: Understand Trie structure
A Trie stores characters of words in a tree where each node represents a character, allowing prefix sharing.Step 2: Identify Trie use in word search
Because words share prefixes, Trie allows fast prefix-based search, making word search efficient.Final Answer:
To efficiently store and search words by their prefixes -> Option CQuick Check:
Trie = prefix search [OK]
- Confusing Trie with sorting structures
- Thinking Trie stores words linearly
- Assuming Trie is for arithmetic
Solution
Step 1: Check Trie node structure for word search
Trie nodes typically have an array of pointers for 26 letters and a boolean to mark word end.Step 2: Match with options
class TrieNode { public: TrieNode* children[26]; bool isEndOfWord; }; matches this structure exactly with children array and isEndOfWord flag.Final Answer:
class TrieNode { public: TrieNode* children[26]; bool isEndOfWord; }; -> Option AQuick Check:
Trie node = children array + end flag [OK]
- Using linked list pointers instead of array
- Using vector<int> instead of pointers
- Confusing binary tree node with Trie node
class TrieNode {
public:
TrieNode* children[26] = {nullptr};
bool isEndOfWord = false;
};
class Trie {
public:
TrieNode* root;
Trie() { root = new TrieNode(); }
void insert(string word) {
TrieNode* node = root;
for (char c : word) {
int index = c - 'a';
if (!node->children[index])
node->children[index] = new TrieNode();
node = node->children[index];
}
node->isEndOfWord = true;
}
bool search(string word) {
TrieNode* node = root;
for (char c : word) {
int index = c - 'a';
if (!node->children[index])
return false;
node = node->children[index];
}
return node->isEndOfWord;
}
};
int main() {
Trie trie;
trie.insert("cat");
trie.insert("car");
trie.insert("dog");
cout << (trie.search("cat") ? "Found" : "Not Found") << endl;
return 0;
}Solution
Step 1: Insert words "cat", "car", "dog" into Trie
Each word is inserted character by character, creating nodes and marking end of word for last character.Step 2: Search for "cat" in Trie
Traversal finds nodes for 'c', 'a', 't' and confirms isEndOfWord is true, so returns true.Final Answer:
Found -> Option BQuick Check:
Inserted word found = Found [OK]
- Not marking isEndOfWord true on insert
- Returning true without checking end flag
- Off-by-one errors in indexing
bool search(string word) {
TrieNode* node = root;
for (char c : word) {
int index = c - 'a';
if (node->children[index])
return false;
node = node->children[index];
}
return node->isEndOfWord;
}Solution
Step 1: Analyze the if condition inside loop
The condition 'if (node->children[index]) return false;' wrongly returns false if child exists, which is opposite logic.Step 2: Correct the condition to check if child does NOT exist
It should be 'if (!node->children[index]) return false;' to return false when path breaks.Final Answer:
Change 'if (node->children[index])' to 'if (!node->children[index])' -> Option DQuick Check:
Check for missing child = return false [OK]
- Returning false when child exists
- Ignoring null pointer checks
- Incorrect index calculation
Solution
Step 1: Insert all words into Trie
Each word is inserted character by character, building a prefix tree.Step 2: Traverse Trie nodes for prefix "app"
Follow nodes for 'a', 'p', 'p' to reach prefix node, then collect all words below it.Step 3: Collect descendant words
Perform DFS or BFS from prefix node to gather all words starting with "app" efficiently.Final Answer:
Insert all words into Trie, then traverse nodes for 'a'->'p'->'p' and collect all descendant words -> Option AQuick Check:
Trie prefix traversal + collect descendants = Insert all words into Trie, then traverse nodes for 'a'->'p'->'p' and collect all descendant words [OK]
- Using sorting instead of Trie for prefix search
- Checking prefix by substring on all words
- Scanning linked list inefficiently
Ready to prove it?
Pass the test and this pattern moves unknown
