01题目描述
02整体思想
3.bool _search_2(string & word)
原理如图示
04 bool _search_2(string & word)
对应的代码逻辑如下
bool _search_2(string & word){
TrieNode *cur=this; // cur一开始 指向根节点,然后分别将第1、2、3、...个字母改变,判断是否能匹配成功
for( int j=0;j<word.size();j++){
int idx=word[j]-'a';
if(_search_1(cur,word, j)) return true; //cur 起始指向根节点,word[0]字母改变, 判断余下的字母能否完全匹配
cur=cur->nodes[idx];//说明word[j]改变无法匹配成功
if(cur==nullptr) return false;
}
return false;
}
05 _search_1(cur,word, j)
的原理
改变word[j]
为cur
的非空子节点a
,返回以a
的子树中是否包含word[j+1:-1]
06 bool _search(TrieNode *cur, string & word , int i)
的原理
//判断字符串 word[i:-1]是否是在以cur 为根结点的前缀树中
bool _search(TrieNode *cur, string & word , int i){
for(int j=i;j<word.size();j++){
int idx=word[j]-'a';
if(cur->nodes[idx]==nullptr) return false;
cur=cur->nodes[idx];
}
return cur->tag==1;
}
07 完整代码
class TrieNode{
public:
vector<TrieNode*> nodes;
bool tag=0;
TrieNode():nodes(26,nullptr){}
// 字典树插入字符串
void insert(string & word){
TrieNode *cur=this;
for(auto ch:word){
int idx=ch-'a';
if(cur->nodes[idx]==nullptr) cur->nodes[idx]=new TrieNode();
cur=cur->nodes[idx];
}
cur->tag=1;
}
//判断字符串 word[i:-1]是否是在以cur 为根结点的前缀树中
bool _search(TrieNode *cur, string & word , int i){
for(int j=i;j<word.size();j++){
int idx=word[j]-'a';
if(cur->nodes[idx]==nullptr) return false;
cur=cur->nodes[idx];
}
return cur->tag==1;
}
//当前位于前缀树的节点为cur, 且第i个为替换字母,即cur->nodes[i]==nullptr,考虑word[i+1]是否和cur->nodes[j] 匹配;
//例子 bcd ba
bool _search_1(TrieNode * cur,string & word, int i) {
for(int j=0;j<26;j++){
if(j==word[i]-'a' || cur->nodes[j]==nullptr) continue;
if(_search(cur->nodes[j],word,i+1)) {
return true;}
}
return false;
}
bool _search_2(string & word){
TrieNode *cur=this;
for( int j=0;j<word.size();j++){
int idx=word[j]-'a';
if(_search_1(cur,word, j)) return true;
cur=cur->nodes[idx];
if(cur==nullptr) return false;
}
return false;
}
bool search(string & word){
int sz=word.size();
TrieNode *cur=this;
return _search_2(word);
}
};
class MagicDictionary {
public:
/** Initialize your data structure here. */
TrieNode *root;
MagicDictionary() {
root=new TrieNode();
}
void buildDict(vector<string> dictionary) {
for(auto & dic:dictionary){
root->insert(dic);
}
}
bool search(string searchWord) {
return root->search(searchWord);
}
};
/**
* Your MagicDictionary object will be instantiated and called as such:
* MagicDictionary* obj = new MagicDictionary();
* obj->buildDict(dictionary);
* bool param_2 = obj->search(searchWord);
*/