题目链接:LCR 064. 实现一个魔法字典 - 力扣(LeetCode)
题目:
请实现有如下两个操作的神奇字典。
-
函数 buildDict,输入单词数组用来创建一个字典。
-
函数 search,输入一个单词,判断能否修改该单词中的一个字符,使修改之后的单词是字典中的一个单词。
例如,输入 ["happy", "new", "year"] 创建一个神奇字典。如果输入单词 "now" 进行查找操作,由于将其中的 'o' 修改成 'e' 就可以得到字典中的 "new",因此返回 true。如果输入单词 "new",那么将其中的任意字符修改成另一个不同的字符都无法得到字典中的单词,因此返回 false。
分析:
可以将单词数组中的单词都保存到前缀树中,然后在前缀树中查找只修改一个字符的单词。
代码实现:
struct TrieNode {
vector<TrieNode*> children;
bool isWord;
TrieNode() : children(26, nullptr), isWord(false) {}
};
class MagicDictionary {
public:
MagicDictionary() : root(new TrieNode) {}
void buildDict(vector<string> dictionary) {
for (string& word : dictionary)
{
TrieNode* cur = root;
for (char ch : word)
{
int index = ch - 'a';
if (cur->children[index] == nullptr)
cur->children[index] = new TrieNode;
cur = cur->children[index];
}
cur->isWord = true;
}
}
bool search(string searchWord) {
return dfs(root, searchWord, 0, false);
}
private:
bool dfs(TrieNode* cur, string& searchWord, int pos, bool isModified)
{
if (pos == searchWord.size())
return cur->isWord && isModified;
int index = searchWord[pos] - 'a';
if (cur->children[index])
{
if (dfs(cur->children[index], searchWord, pos + 1, isModified))
return true;
}
if (isModified == false)
{
for (int i = 0; i < 26; ++i)
{
if (i != index && cur->children[i])
{
if (dfs(cur->children[i], searchWord, pos + 1, true))
return true;
}
}
}
return false;
}
private:
TrieNode* root;
};