• leetcode-676:实现一个魔法字典


    leetcode-676:实现一个魔法字典

    题目

    题目连接
    设计一个使用单词列表进行初始化的数据结构,单词列表中的单词 互不相同 。 如果给出一个单词,请判定能否只将这个单词中一个字母换成另一个字母,使得所形成的新单词存在于你构建的字典中。

    实现 MagicDictionary 类:

    • MagicDictionary() 初始化对象
    • void buildDict(String[] dictionary) 使用字符串数组 dictionary 设定该数据结构,dictionary 中的字符串互不相同
    • bool search(String searchWord) 给定一个字符串 searchWord ,判定能否只将字符串中 一个 字母换成另一个字母,使得所形成的新字符串能够与字典中的任一字符串匹配。如果可以,返回 true ;否则,返回 false 。

    示例:

    输入
    ["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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    解题

    方法一:字典树+dfs

    参考链接

    字典树的构建就是常规的构建方法
    就dfs有所区别

    dfs里面有两种情况

    • 当前字符在字典树中存在,继续dfs
    • 暴力遍历26个字母,继续dfs。通过limit标志位去标志,只能更换一次字母。
    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;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
  • 相关阅读:
    面经-虚拟机-对象引用类型
    Android车载应用与手机版Android应用有何不同?
    【Java】默认修饰符总结
    扫盲低代码——构建的基本原理
    [附源码]计算机毕业设计JAVA校园兼职招聘系统
    变分推断(Variational Inference)解析
    金仓数据库KingbaseES客户端编程接口指南-JDBC(10. JDBC 读写分离最佳实践)
    RGMII接口--->(010)FPGA实现RGMII接口(十)
    Spring基于Annotation装配Bean
    使用Python将MP4视频转换为图像
  • 原文地址:https://blog.csdn.net/qq_21539375/article/details/125787063