211. Design Add and Search Words Data Structure
阿新 • • 發佈:2021-01-11
問題:
設計一個字典資料結構,存在以下方法:
- 構造該資料結構變數: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() { 56 } 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 */