题目:676. 实现一个魔法字典
方法一:先将dictionary中的字符串都用集合set来保存,实现哈希表的目的。然后在search方法当中,枚举集合set当中的所有元素来进行比对即可,时间复杂度为0(10^6)。细节看注释
class MagicDictionary {
public:
//集合set来保存dictionary中的字符串
set<string> st;
MagicDictionary() {
st.clear();
}
void buildDict(vector<string> dictionary) {
//集合set来保存dictionary中的字符串
for(auto x:dictionary){
st.insert(x);
}
}
bool search(string searchWord) {
//答案
bool flag=0;
//枚举集合set当中的所有元素x
for(auto x:st){
//剪枝:长度不相等直接下一个
if(x.size()!=searchWord.size()) continue;
//计算有多少个不同字符
int ans=0;
for(int i=0;i<searchWord.size();i++){
if(x[i]!=searchWord[i]) ans++;
}
//不同的字符为1,说明存在
if(ans==1){
flag=1;
break;
}
}
return flag;
}
};
/**
* Your MagicDictionary object will be instantiated and called as such:
* MagicDictionary* obj = new MagicDictionary();
* obj->buildDict(dictionary);
* bool param_2 = obj->search(searchWord);
*/
方法二:字典树。将dictionary中的字符串都用字典树来存储。然后在search方法当中进行比对。细节看注释
模板题:(Trie +字典树+贪心) acwing 143. 最大异或对
class MagicDictionary {
public:
//字典树
int p[10010][30];
int cnt[10010];
int idx=1;
MagicDictionary() {
memset(p,0,sizeof p);
memset(cnt,0,sizeof cnt);
}
void buildDict(vector<string> dictionary) {
//将dictionary中的字符串都用字典树来存储
for(auto x:dictionary){
int id=1;
for(auto t:x){
//cout<<t-'a'<<":"<<t<<":";
int& tmp=p[id][t-'a'];
//cout<<tmp<<endl;
if(tmp==0){
tmp=++idx;
}
id=tmp;
}
cnt[id]++;
}
}
//参数:u:字典树的位置、pos:字符串searchWord遍历到的位置、modify:是否修改过一次
bool dfs(int u,int pos,string searchWord,bool modify){
//如果遍历完了字符串searchWord
if(pos==searchWord.size()){
//修改次数为1,且有这个比对字符串的存在,则返回true
return modify&&cnt[u];
}
//找到字典树中的位置
int tmp=p[u][searchWord[pos]-'a'];
//标记答案
bool flag=0;
if(tmp) flag=dfs(tmp,pos+1,searchWord,modify);
//这里还判断flag的原因是,即使tmp不为0,但也有可能出现其他字符串,就当前位置不同,其余都相同的情况。
if(flag==0&&modify==false){
//遍历26个字母
for(int i=0;i<26;i++){
int tmp2=p[u][i];
//如果当前字母和searchWord[pos]相同,或者字典树中不存在
if(i==searchWord[pos]-'a'||tmp2==0) continue;
//如果返回的是true ,直接修改flag,跳出即可
if(dfs(tmp2,pos+1,searchWord,true)){
flag=1;
break;
}
}
}
return flag;
}
bool search(string searchWord) {
//参数:u:字典树的位置、pos:字符串searchWord遍历到的位置、modify:是否修改过一次
return dfs(1,0,searchWord,false);
}
};
/**
* Your MagicDictionary object will be instantiated and called as such:
* MagicDictionary* obj = new MagicDictionary();
* obj->buildDict(dictionary);
* bool param_2 = obj->search(searchWord);
*/