题目连接
设计一个使用单词列表进行初始化的数据结构,单词列表中的单词 互不相同 。 如果给出一个单词,请判定能否只将这个单词中一个字母换成另一个字母,使得所形成的新单词存在于你构建的字典中。
实现 MagicDictionary 类:
示例:
输入
["MagicDictionary", "buildDict", "search", "search", "search", "search"]
[[], [["hello", "leetcode"]], ["hello"], ["hhllo"], ["hell"], ["leetcoded"]]
输出
[null, null, false, true, false, false]
解释
MagicDictionary magicDictionary = new MagicDictionary();
magicDictionary.buildDict(["hello", "leetcode"]);
magicDictionary.search("hello"); // 返回 False
magicDictionary.search("hhllo"); // 将第二个 'h' 替换为 'e' 可以匹配 "hello" ,所以返回 True
magicDictionary.search("hell"); // 返回 False
magicDictionary.search("leetcoded"); // 返回 False
字典树的构建就是常规的构建方法
就dfs有所区别
dfs里面有两种情况
class Trie{
public:
bool isEnd=false;
vector<Trie*> next=vector<Trie*>(26,nullptr);
};
class MagicDictionary {
public:
Trie* trie=new Trie();
MagicDictionary() {
}
//api
void buildDict(vector<string> dictionary) {
for(string& word:dictionary){
insert(word);
}
}
//api
bool search(string searchWord) {
return dfs(trie,searchWord,0,1);
}
bool dfs(Trie* node,string& word,int startIndex,int limit){//limit表示是否还能修改字母
if(startIndex==word.size()){
return limit==0&&node->isEnd;
}
int i=word[startIndex]-'a';
if(node->next[i]){//如果当前前缀能在字典树中找到,那么就接着dfs
if(dfs(node->next[i],word,startIndex+1,limit)) return true;
}
if(limit==1){//如果没有修改过字母,就暴力遍历26个字母
for(int j=0;j<26;j++){
if(j!=i&&node->next[j]){
if(dfs(node->next[j],word,startIndex+1,limit-1)) return true;
}
}
}
return false;
}
void insert(string& word){
Trie* node=trie;
for(char c:word){
if(node->next[c-'a']==nullptr){
node->next[c-'a']=new Trie();
}
node=node->next[c-'a'];
}
node->isEnd=true;
}
};