LeetCode 676. 實現一個魔法字典(Trie+暴力 || DFS)

實現一個魔法字典
前綴樹存儲單詞。然後對要查詢的每個單詞,對它的每個位置去替代一個不同的字符,然後去字典樹裏面查詢存在與否即可。

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);
 */

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章