【数据结构-字典树】力扣211. 添加与搜索单词 - 数据结构设计
请你设计一个数据结构,支持 添加新单词 和 查找字符串是否与任何先前添加的字符串匹配 。
实现词典类 WordDictionary :
WordDictionary() 初始化词典对象
void addWord(word) 将 word 添加到数据结构中,之后可以对它进行匹配
bool search(word) 如果数据结构中存在字符串与 word 匹配,则返回 true ;否则,返回 false 。word 中可能包含一些 ‘.’ ,每个 . 都可以表示任何一个字母。
示例:
输入:
[“WordDictionary”,“addWord”,“addWord”,“addWord”,“search”,“search”,“search”,“search”]
[[],[“bad”],[“dad”],[“mad”],[“pad”],[“bad”],[“.ad”],[“b…”]]
输出:
[null,null,null,null,false,true,true,true]
解释:
WordDictionary wordDictionary = new WordDictionary();
wordDictionary.addWord(“bad”);
wordDictionary.addWord(“dad”);
wordDictionary.addWord(“mad”);
wordDictionary.search(“pad”); // 返回 False
wordDictionary.search(“bad”); // 返回 True
wordDictionary.search(“.ad”); // 返回 True
wordDictionary.search(“b…”); // 返回 True
提示:
1 <= word.length <= 25
addWord 中的 word 由小写英文字母组成
search 中的 word 由 ‘.’ 或小写英文字母组成
最多调用 104 次 addWord 和 search
字典树
class WordDictionary {
private:
bool isEnd;
vector<WordDictionary*> children;
public:
WordDictionary(): children(26, nullptr), isEnd(false) {}
bool searchHelper(string& word, int index){
WordDictionary* node = this;
for(int i = index; i < word.size(); i++){
char ch = word[i];
if(ch == '.'){
for(WordDictionary* child : node->children){
if(child && child->searchHelper(word, i + 1)){
return true;
}
}
return false;
}else{
ch -= 'a';
if(node->children[ch] == nullptr){
return false;
}
node = node->children[ch];
}
}
return node->isEnd;
}
void addWord(string word) {
WordDictionary* node = this;
for(char ch : word){
ch -= 'a';
if(node->children[ch] == nullptr){
node->children[ch] = new WordDictionary();
}
node = node->children[ch];
}
node->isEnd = true;
}
bool search(string word) {
return searchHelper(word, 0);
}
};
这道题对比传统的字典树,在search的时候可能会遇到’.‘来代替任何一个字符。所以当遇到’.‘的时候,我们就遍历当前节点的所有children,也就是代表’.‘被当成了任意一个字符,然后开始遍历。要注意的是在递归的时候,需要调用child->searchHelper,这是因为child代表的是’.‘代替的字符,这样递归的时候node才能指向正确的位置,如果递归返回的是true,那么说明将’.‘替换成child字符是可行的,如果所有替换成任意child都不可行,那么返回false。当遍历的字符不是’.'点时候,就是正常字典树的search流程。