• 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
  • 相关阅读:
    java计算机毕业设计宠物寄存管理系统MyBatis+系统+LW文档+源码+调试部署
    Zygisk-IL2CppDumper对抗方案
    GStreamer 进阶
    Rust个人学习之结构体
    java之string类用法详解
    Sparse稀疏检索介绍与实践
    内存和缓存?
    CentOS 7离线升级OpenSSH至9.1p1操作过程及遇上的问题
    Servlet的生命周期
    第十五章 源代码文件 REST API 简介
  • 原文地址:https://blog.csdn.net/qq_21539375/article/details/125787063