LeetCode211. 新增與搜尋單詞 - 資料結構設計
阿新 • • 發佈:2020-08-13
這題和LeetCode208. 實現 Trie (字首樹)一樣,都是實現Trie樹,
支援字串的插入和查詢,只不過這裡的查詢需要支援正則表示式,也就是可以用'.'代替任何單詞,所以我們需要在查詢部分做一些修改,
插入單詞部分和208題一樣。
對於查詢單詞,由於需要支援正則表示式,所以在查詢單詞word的某個位置如果是'.'時,需要對於當前樹的所有子樹進行搜尋,因此我們
需要額外寫一個dfs函式對字串進行查詢。
這裡就在程式碼部分重點講一下dfs函式,其他部分和208題一致,可以看我上面那個連結,這裡就不細講了。
程式碼如下:
class WordDictionary { public: struct Node { Node* son[26]; bool is_end; Node() { for(int i = 0; i < 26; ++i) { son[i] = NULL; } is_end = false; } }*root; /** Initialize your data structure here. */ WordDictionary() { root = new Node(); } /** Adds a word into the data structure. */ void addWord(string word) { Node* p = root; for(int i = 0; i < word.size(); ++i) { int u = word[i] - 'a'; if(p -> son[u] == NULL) { p -> son[u] = new Node(); } p = p -> son[u]; } p -> is_end = true; } /** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */ bool search(string word) { return dfs(root, word, 0); //從根節點(空)開始,搜尋單詞word,第三個引數表示當前已匹配前多少個字母 } bool dfs(Node* p, string &word, int i) { if(i == word.size()) { //如果所有單詞都匹配,即在trie樹中存在路徑和word相等,則需要判斷結尾的is_end標記是否為true return p -> is_end; } if(word[i] != '.') { //如果當前字母不是萬用字元'.',則不需要列舉所有可能的路徑 int u = word[i] - 'a'; if(p -> son[u] == NULL) { //只需要看當前字母是否有word[i]這個兒子就好 return false; } p = p -> son[u]; //如果有這個兒子,繼續往下遞迴搜尋,匹配word的剩餘部分 return dfs(p, word, i + 1); } else { for(int j = 0; j < 26; ++j) { //如果當前字母是萬用字元'.',則需要遞迴搜尋所有的兒子進行匹配 if(p -> son[j] != NULL && dfs(p -> son[j], word, i + 1) == true) { //如果沿著某個子樹匹配成功,則返回true return true; } } return false; //所有路徑都無法匹配,返回false } } }; /** * Your WordDictionary object will be instantiated and called as such: * WordDictionary* obj = new WordDictionary(); * obj->addWord(word); * bool param_2 = obj->search(word); */