LeetCode 211. Design Add and Search Words Data Structure
原题链接在这里:https://leetcode.com/problems/design-add-and-search-words-data-structure/
题目:
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)
Addsword
to the data structure, it can be matched later.bool search(word)
Returnstrue
if there is any string in the data structure that matchesword
orfalse
otherwise.word
may 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
word
inaddWord
consists lower-case English letters.word
insearch
consist of'.'
or lower-case English letters.- At most
50000
calls will be made toaddWord
andsearch
.
Note:
You may assume that all words are consist of lowercase letters a-z
.
题解:
查找词用到Trie树.
addword和Implement Trie (Prefix Tree)相同. search时利用dfs, 终止条件有两种.
一种是string 还没扫完, 已经走到了null节点, return false.
另一种扫完了string, 要看是否到了Trie树的叶子节点.
dfs过程分两种情况,一种情况是当前char 是'.', 此时应该跳过这个char, 同时对剩余string和tn.nexts 的所有储存的节点继续迭代,若有一个正好走到叶子节点, 就返回ture; 若没有一个正好走到叶子节点,就return false.
另一种情况是当前char不是'.', 就继续用root.nexts[c-'a'] 和 word, i+1 index做dfs.
Time Complexity: addWord, O(n). search, O(26^n), n是string 长度. worst case每一个路径都要扫.
Space: (m*n). m is number of words added.
AC Java:
1 class WordDictionary { 2 TrieNode root; 3 4 /** Initialize your data structure here. */ 5 public WordDictionary() { 6 root = new TrieNode(); 7 } 8 9 /** Adds a word into the data structure. */ 10 public void addWord(String word) { 11 TrieNode p = root; 12 for(char c : word.toCharArray()){ 13 if(p.nexts[c - 'a'] == null){ 14 p.nexts[c - 'a'] = new TrieNode(); 15 } 16 17 p = p.nexts[c - 'a']; 18 } 19 20 p.val = word; 21 } 22 23 /** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */ 24 public boolean search(String word) { 25 if(word == null || word.length() == 0){ 26 return false; 27 } 28 29 return searchWord(word, 0, root); 30 } 31 32 private boolean searchWord(String word, int index, TrieNode p){ 33 if(p == null){ 34 return false; 35 } 36 37 if(index == word.length()){ 38 return p.val != null; 39 } 40 41 if(word.charAt(index) == '.'){ 42 for(TrieNode next : p.nexts){ 43 if(searchWord(word, index + 1, next)){ 44 return true; 45 } 46 } 47 48 }else{ 49 return searchWord(word, index + 1, p.nexts[word.charAt(index) - 'a']); 50 } 51 52 return false; 53 } 54 } 55 56 class TrieNode{ 57 String val; 58 TrieNode [] nexts; 59 60 public TrieNode(){ 61 nexts = new TrieNode[26]; 62 } 63 } 64 65 /** 66 * Your WordDictionary object will be instantiated and called as such: 67 * WordDictionary obj = new WordDictionary(); 68 * obj.addWord(word); 69 * boolean param_2 = obj.search(word); 70 */
AC Python:
1 class WordDictionary: 2 3 def __init__(self): 4 """ 5 Initialize your data structure here. 6 """ 7 self.root = TrieNode() 8 9 def addWord(self, word: str) -> None: 10 p = self.root 11 for c in word: 12 if c not in p.next: 13 p.next[c] = TrieNode() 14 p = p.next[c] 15 p.val = word 16 17 def search(self, word: str) -> bool: 18 if not word: 19 return False 20 21 p = self.root 22 return self.dfs(word, 0, p) 23 24 def dfs(self, word, ind, p): 25 if ind == len(word): 26 if p.val: 27 return True 28 else: 29 return False 30 31 if word[ind] == ".": 32 return any([self.dfs(word, ind + 1, can) for can in p.next.values()]) 33 34 else: 35 if word[ind] not in p.next: 36 return False 37 return self.dfs(word, ind + 1, p.next[word[ind]]) 38 39 class TrieNode: 40 def __init__(self): 41 self.val = "" 42 self.next = {}