1. 程式人生 > 實用技巧 >211. Design Add and Search Words Data Structure

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 */