trie
backtracking
recursion
]
Leetcode 0211. Design Add and Search Words Data Structure
https://leetcode.com/problems/design-add-and-search-words-data-structure
In this problem, we need to use Trie data structure. For more details go to the problem 208. Implement Trie (Prefix Tree).
So, what we have here?
TrieNode
class with two values: dictionary of children and flag, if this node is end of some word.- Now, we need to implement
addWord(self, word)
function: we add symbol by symbol, and go deepere and deeper in our Trie. In the end we note our node as end node. - Now, about
search(self, word)
function. Here we usedfs(node, i)
with backtracking, because we can have symbol.
in our word (herenode
is link to Trie node andi
is index of letter inword
). So we need to check all options: we go to all possible children and calldfs
recursively. If we found not.
, but just some letter, we check if we have this letter as children, and if we have, we go deeper. If we are out of letters, that isi == len(word)
, we returnTrue
if currentend_node
is equal to1
and false in opposite case. Finally, we returnFalse
if we can not go deeper, but we still have letters. - Now, we just return
dfs(self.root, 0)
.
Complexity: Easy part is space complexity, it is O(M)
, where M
is sum of lengths of all words in our Trie. This is upper bound: in practice it will be less than M
and it depends, how much words are intersected. The worst time complexity is also O(M)
, potentially we can visit all our Trie, if we have pattern like .....
. For words without .
, time complexity will be O(h)
, where h
is height of Trie. For words with several letters and several .
, we have something in the middle.
class TrieNode:
def __init__(self):
self.children = {}
self.end_node = 0
class WordDictionary:
def __init__(self):
self.root = TrieNode()
def addWord(self, word):
root = self.root
for symbol in word:
root = root.children.setdefault(symbol, TrieNode())
root.end_node = 1
def search(self, word):
def dfs(node, i):
if i == len(word): return node.end_node
if word[i] == ".":
for child in node.children:
if dfs(node.children[child], i+1): return True
if word[i] in node.children:
return dfs(node.children[word[i]], i+1)
return False
return dfs(self.root, 0)
If you like the solution, you can upvote it on leetcode discussion section: Problem 0211