實現一個魔法字典
前綴樹存儲單詞。然後對要查詢的每個單詞,對它的每個位置去替代一個不同的字符,然後去字典樹裏面查詢存在與否即可。
class MagicDictionary {
struct Node{
bool isEnd=false;
Node* children[26] = {0};
};
Node* root = nullptr;
void insert(const string& s){
Node* p = root;
for(char c:s){
if(!p->children[c-'a']){
p->children[c-'a'] = new Node;
}
p = p->children[c-'a'];
}
p->isEnd = true;
}
bool ask(const string& s){
Node* p = root;
for(char c:s){
if(!p->children[c-'a']){
return false;
}
p = p->children[c-'a'];
}
return p->isEnd;
}
public:
/** Initialize your data structure here. */
MagicDictionary() {
root = new Node;
}
/** Build a dictionary through a list of words */
void buildDict(vector<string> dict) {
for(string& s:dict){
insert(s);
}
}
/** Returns if there is any word in the trie that equals to the given word after modifying exactly one character */
bool search(string word) {
for(int i=0;i<word.size();i++){
char old = word[i];
for(char c='a';c<='z';c++){
if(old==c){
continue;
}
word[i] = c;
if(ask(word)){
return true;
}
}
word[i] = old;
}
return false;
}
};
/**
* Your MagicDictionary object will be instantiated and called as such:
* MagicDictionary* obj = new MagicDictionary();
* obj->buildDict(dict);
* bool param_2 = obj->search(word);
*/
DFS優化版、省去一些冗餘的比較:
其餘的代碼沒有改變,只是查找的時候用dfs實現,狀態轉移量Node*,int idx
,過程量int changed
。只有當搜索到字符串的終點,並且恰好變化了一次,並且節點是某個字符串的結尾,才能返回true。
注意一個剪枝:如果changed>1
立即回溯。
class MagicDictionary {
struct Node{
bool isEnd=false;
Node* children[26] = {0};
};
Node* root = nullptr;
void insert(const string& s){
Node* p = root;
for(char c:s){
if(!p->children[c-'a']){
p->children[c-'a'] = new Node;
}
p = p->children[c-'a'];
}
p->isEnd = true;
}
bool ask(const string& s){
return dfs(s,root,0,0);
}
bool dfs(const string& s,Node* p,int idx,int changed){
if(idx==s.size() && changed==1 && p->isEnd){
return true;
}
if(changed>1){
return false;
}
for(int i=0;i<26;i++){
if(p->children[i]){
if(i==s[idx]-'a'){
if(dfs(s,p->children[i],idx+1,changed)){
return true;
}
}else{
if(dfs(s,p->children[i],idx+1,changed+1)){
return true;
}
}
}
}
return false;
}
public:
MagicDictionary() {
root = new Node;
}
void buildDict(vector<string> dict) {
for(string&s:dict){
insert(s);
}
}
bool search(string word) {
return ask(word);
}
};
這題測試數據太水了,這都可以過。
class MagicDictionary {
public:
set<string> st;
/** Initialize your data structure here. */
MagicDictionary() {//構造函數
}
/** Build a dictionary through a list of words */
void buildDict(vector<string> dict) {
for(int i = 0; i < dict.size(); i++){
st.insert(dict[i]);
}
}
/** Returns if there is any word in the trie that equals to the given word after modifying exactly one character */
bool search(string word) {
if(st.empty()) return false;
for(auto str : st){
if(str.size() != word.size()) continue;
if(str == word) continue;
if(is_changed(str, word)) return true;
}
return false;
}
bool is_changed(string str1, string str2){
int length = str1.size();
int cnt = 0;
for(int i = 0; i < length; i++){
if(str1[i] != str2[i]) cnt++;
}
if(cnt == 1) return true;
else return false;
}
};
/**
* Your MagicDictionary object will be instantiated and called as such:
* MagicDictionary* obj = new MagicDictionary();
* obj->buildDict(dict);
* bool param_2 = obj->search(word);
*/