題目地址:Add and Search Word - Data structure design
題目簡介:
設計一個支持以下兩種操作的數據結構:
void addWord(word)
bool search(word)
可以搜索文字或正則表達式字符串,字符串只包含字母 . 或 a-z 。其中'.' 可以表示任何一個字母。
示例:
addWord("bad")
addWord("dad")
addWord("mad")
search("pad") -> false
search("bad") -> true
search(".ad") -> true
search("b..") -> true
說明: 你可以假設所有單詞都是由小寫字母 a-z 組成的。
題目解析:
C++提供的String類型便能夠很好完成這個任務,這裏需要自己實現。結合前面剛學到的Implement Trie (Prefix Tree),這裏只需要把search函數定義好即可。怎麼判斷是否出現過呢?最主要的是'.'的處理方法,因爲'.'可以代表任何一個字符,所以出現時將其代表爲任意字符的情況便是遍歷所有的子節點,只要出現一個滿足條件的即可。於是進行修改Implement Trie (Prefix Tree)代碼如下:
C++:
class TrieNode {
public:
vector<TrieNode*> child;
bool isWord;
TrieNode() : isWord(false), child(26, nullptr) {
}
~TrieNode() {
for (auto& c : child)
delete c;
}
};
class WordDictionary {
public:
/** Initialize your data structure here. */
WordDictionary() {
root = new TrieNode();
}
/** Adds a word into the data structure. */
void addWord(string word) {
TrieNode* p = root;
for (char a : word) {
int i = a - 'a';
if (!p -> child[i])
p -> child[i] = new TrieNode();
p = p -> child[i];
}
p -> isWord = 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 searchWord(word, root, 0);
}
bool searchWord(string &word, TrieNode *p, int i) {
if (i == word.size())
return p -> isWord;
if (word[i] == '.')
{
for (auto &a : p->child)
{
if (a && searchWord(word, a, i + 1))
return true;
}
return false;
}
else
{
return p -> child[word[i] - 'a'] && searchWord(word, p -> child[word[i] - 'a'], i + 1);
}
}
private:
TrieNode* root;
};
/**
* Your WordDictionary object will be instantiated and called as such:
* WordDictionary* obj = new WordDictionary();
* obj->addWord(word);
* bool param_2 = obj->search(word);
*/
Python:
class Node(object):
def __init__(self):
self.children = collections.defaultdict(Node)
self.isword = False
class WordDictionary(object):
def __init__(self):
"""
Initialize your data structure here.
"""
self.root = Node()
def addWord(self, word):
"""
Adds a word into the data structure.
:type word: str
:rtype: None
"""
current = self.root
for w in word:
current = current.children[w]
current.isword = True
def search(self, word):
"""
Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter.
:type word: str
:rtype: bool
"""
def helper(word, root, i):
if i == len(word):
return root.isword
curr_ch = word[i]
if curr_ch == '.':
for _, next_node in root.children.items():
if helper(word, next_node, i + 1):
return True
return False
if curr_ch in root.children:
return helper(word, root.children[curr_ch], i + 1)
return False
return helper(word, self.root, 0)
# Your WordDictionary object will be instantiated and called as such:
# obj = WordDictionary()
# obj.addWord(word)
# param_2 = obj.search(word)