A Trie is a tree-like data structure that stores strings by breaking them down into
individual characters. Each node represents a character and has
26 children
(for English
letters). The
'insert' operation
adds
characters
level by level
, creating
new nodes as needed and marking the end with a boolean. For
'search'
, we traverse
the tree checking if all characters exist and
verify the end marker
.
The
'startsWith'
operation is
similar but doesn't require the end marker.
class Trie { public: struct TrieNode { TrieNode* children[26]; bool isEndCharacter; TrieNode() { isEndCharacter = false; for (int i = 0; i < 26; i++) children[i] = NULL; } }; TrieNode* root; Trie() { root = new TrieNode(); } // Idea is to make a N-ary tree where each nodes has 26 children. void insert(string word) { TrieNode* copy = root; for (int i = 0; i < word.size(); i++) { char ch = word[i]; if (copy->children[ch - 'a'] == NULL) { copy->children[ch - 'a'] = new TrieNode(); } copy = copy->children[ch - 'a']; } copy->isEndCharacter = true; } bool search(string word) { TrieNode* copy = root; for (int i = 0; i < word.size(); i++) { char ch = word[i]; if (copy->children[ch - 'a'] == NULL) return false; copy = copy->children[ch - 'a']; } if (copy->isEndCharacter) return true; else return false; } bool startsWith(string prefix) { TrieNode* copy = root; for (int i = 0; i < prefix.size(); i++) { char ch = prefix[i]; if (copy->children[ch - 'a'] == NULL) return false; copy = copy->children[ch - 'a']; } return true; } }; /** * Your Trie object will be instantiated and called as such: * Trie* obj = new Trie(); * obj->insert(word); * bool param_2 = obj->search(word); * bool param_3 = obj->startsWith(prefix); */
Each operation (insert/search/startsWith) processes each character exactly once, where 'n'
is the
length of the input string.
Where
'm'
is
average word length and 'n'
is number of
words, as each character may require a new
node.