211-design-add-and-search-words-data-structure¶
Try it on leetcode
Description¶
Design a data structure that supports adding new words and finding if a string matches any previously added string.
Implement the WordDictionary class:
- WordDictionary()Initializes the object.
- void addWord(word)Adds- wordto the data structure, it can be matched later.
- bool search(word)Returns- trueif there is any string in the data structure that matches- wordor- falseotherwise.- wordmay contain dots- '.'where dots can be matched with any letter.
Example:
Input
["WordDictionary","addWord","addWord","addWord","search","search","search","search"]
[[],["bad"],["dad"],["mad"],["pad"],["bad"],[".ad"],["b.."]]
Output
[null,null,null,null,false,true,true,true]
Explanation
WordDictionary wordDictionary = new WordDictionary();
wordDictionary.addWord("bad");
wordDictionary.addWord("dad");
wordDictionary.addWord("mad");
wordDictionary.search("pad"); // return False
wordDictionary.search("bad"); // return True
wordDictionary.search(".ad"); // return True
wordDictionary.search("b.."); // return True
Constraints:
- 1 <= word.length <= 500
- wordin- addWordconsists lower-case English letters.
- wordin- searchconsist of- '.'or lower-case English letters.
- At most 50000calls will be made toaddWordandsearch.
Solution(Python)¶
"""
Trie Data structure has 
    key - denotes current char
    children = set of next values (for contant time lookup)
    isEnd = boolean to mark end of the word
"""
class TrieNode:
    def __init__(self):
        self.children = {}
        self.isEnd = False
class WordDictionary:
    """
    intialize empty trie and store in memory
    """
    def __init__(self):
        self.trie = TrieNode()
    """
    algorithm
        initialize curr trie node
        iterate char in word
            check if children has char 
                if true:
                    set curr node as that node
                else:
                    create a trienode with char
                    set curr node as new node
        set curr node isEnd as true
                    
    """
    def addWord(self, word: str) -> None:
        curr = self.trie
        for ch in word:
            if ch not in curr.children:
                curr.children[ch] = TrieNode()
            curr = curr.children[ch]
        curr.isEnd = True
    """
    algorithm
        initialize curr trie node
        fun dfs(index)
            iterate char in word
                if index reaches n:
                return True
                if char is .
                    for all children
                    if dfs(children): return True
                elif char in children:
                    dfs(children of char)
            return  false
                
        return curr.isEnd
            
    """
    def search(self, word: str) -> bool:
        return self.dfs(self.trie, word, 0, len(word))
    def dfs(self, root, word, i, n):
        if i == n:
            return root.isEnd
        if word[i] == ".":
            for child in root.children:
                if self.dfs(root.children[child], word, i + 1, n):
                    return True
        elif word[i] in root.children:
            return self.dfs(root.children[word[i]], word, i + 1, n)
        return False
# Your WordDictionary object will be instantiated and called as such:
# obj = WordDictionary()
# obj.addWord(word)
# param_2 = obj.search(word)