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) Adds word to the data structure, it can be matched later.
  • bool search(word) Returns true if there is any string in the data structure that matches word or false 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 in addWord consists lower-case English letters.
  • word in search consist of  '.' or lower-case English letters.
  • At most 50000 calls will be made to addWord and search.

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 = {}

 

posted @ 2015-11-03 12:07  Dylan_Java_NYC  阅读(548)  评论(0编辑  收藏  举报