设计一个支持以下两种操作的数据结构:
void addWord(word) bool search(word)
search(word) 可以搜索文字或正则表达式字符串,字符串只包含字母 .
或 a-z
。 .
可以表示任何一个字母。
示例:
addWord("bad") addWord("dad") addWord("mad") search("pad") -> false search("bad") -> true search(".ad") -> true search("b..") -> true
说明:
你可以假设所有单词都是由小写字母 a-z
组成的。
思路:这道题本来和回溯法没有关系,唯一用到了递归的是当遇到了‘.’的字符,需要递归的调用其后的每一个字符观察是否满足情况,核心代码如下(其他部分请参考这道题的先选题前缀树,字典树):
if (word[start] == '.') {
for (auto &a : p->child) {
if (a && searchCore(word, a, start + 1)) return true;
}
return false;
}
意思是当当前的字符是'.'时,由于不知道代表具体哪一个字符,所以需要递归遍历子节点的所有情况,如果子节点有一个满足了,就直接返回true
参考代码:
class WordDictionary {
struct TrieNode {
TrieNode* child[26];
bool isword;
TrieNode() :isword(false) {
for (auto &a : child) {
a = nullptr;
}
}
};
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 (auto &a : word) {
int i = a - 'a';
if (!p->child[i]) p->child[i] = new TrieNode();
p = p->child[i];
}
p->isword = true;
}
bool searchCore(string &word,TrieNode *p,int start) {
if (start == word.size()) return p->isword;
if (word[start] == '.') {
for (auto &a : p->child) {
if (a && searchCore(word, a, start + 1)) return true;
}
return false;
}
else{
return p->child[word[start] - 'a'] && searchCore(word, p->child[word[start] - 'a'], start + 1);
}
}
/** 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 searchCore(word, root, 0);
}
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);
*/