211. Design Add and Search Words Data Structure

问题:

设计一个字典数据结构,存在以下方法:

  • 构造该数据结构变量:WordDictionary
  • 加入一个单词:void addWord(word)(该单词的各个字母:a~z)
  • 搜索一个单词:bool search(word)(该单词的各个字母:a~z 再加上 .<可匹配任意a~z字母>)
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.

  

解法:DFS(深度优先搜索)

每次递归:匹配每一个字符。若匹配成功 pos+1,递归匹配下一个字符。

path:要匹配字符串的word,当前匹配到的位置pos

optlists:字典中可选的(待匹配的)所有单词set。

对于本问题,设计字典数据结构

为了节省搜索时间,利用map,对应一些字符串属性,存储对应的字符串set

unordered_map<int, unordered_map<char, unordered_set<string>>> WD;

解释:

第一次map:key:字符串长度length -> value:所有满足该长度的单词(这里继续使用二次map)。

第二次map:key:单词首字母Headc -> value:所有以该首字母开头的单词。(这里使用set,利于进行存在与否判断)。

⚠️  注意:本问题中为了快速搜索定位,对于广义匹配字符'.',我们也存入一个key为'.'的第二次map,这里保存满足length的所有字符串

(即为第二次map的总表,所有满足第二次map的单词都会存一份在这里)。

代码参考:

 1 class WordDictionary {
 2 public:
 3     /** Initialize your data structure here. */
 4     WordDictionary() {
 5         
 6     }
 7     
 8     void addWord(string word) {
 9         int l = word.length();
10         char Headc = word[0];
11         WD[l][Headc].insert(word);
12         WD[l]['.'].insert(word);
13     }
14     
15     bool search(string word) {
16         int l = word.length();
17         char Headc = word[0];
18         if(!WD[l][Headc].size()) return false;
19         if(WD[l][Headc].count(word)) return true;
20         for(string opt:WD[l][Headc]) {
21             if(DFS(word, opt, 0)) return true;
22         }
23         return false;
24     }
25 private:
26     unordered_map<int, unordered_map<char, unordered_set<string>>> WD;
27     bool isValid(char opt, char word) {
28         if(word=='.') return true;
29         if(word!=opt) return false;
30         return true;
31     }
32     bool DFS(string& word, string& opt, int pos) {
33         if(pos==word.length()) return true;
34         if(isValid(opt[pos], word[pos])) {
35             return DFS(word, opt, pos+1);
36         }
37         return false;
38     }
39 };
40 
41 /**
42  * Your WordDictionary object will be instantiated and called as such:
43  * WordDictionary* obj = new WordDictionary();
44  * obj->addWord(word);
45  * bool param_2 = obj->search(word);
46  */
原文地址:https://www.cnblogs.com/habibah-chang/p/14261724.html