LeetCode.676 Implement Magic Dictionary

本文介绍了一种名为“魔法字典”的数据结构实现方法,通过三种不同的技术方案来完成单词的构建与搜索。主要探讨了如何判断一个单词是否可以通过改变一个字符变成字典中的某个单词。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:

Implement a magic directory with buildDict, and search methods.

For the method buildDict, you'll be given a list of non-repetitive words to build a dictionary.

For the method search, you'll be given a word, and judge whether if you modify exactly one character into another character in this word, the modified word is in the dictionary you just built.

Example 1:

Input: buildDict(["hello", "leetcode"]), Output: Null
Input: search("hello"), Output: False
Input: search("hhllo"), Output: True
Input: search("hell"), Output: False
Input: search("leetcoded"), Output: False

Note:

  1. You may assume that all the inputs are consist of lowercase letters a-z.
  2. For contest purpose, the test data is rather small by now. You could think about highly efficient algorithm after the contest.
  3. Please remember to RESET your class variables declared in class MagicDictionary, as static/class variables are persisted across multiple test cases. Please see here for more details
分析1(HashMap实现):

class MagicDictionary {
    //给定单词字典数组,和需要对比的单词,魔术数组的含义是:对比单词中只需要更改一个字符即可在字典数组中找到相同的单词
    //思路:采用对字典中的每个单词每个字母建立映射关系Map(剩下字母,当前字母映射集合)
    //匹配:当前字母不同,剩下的字符串匹配成功,即返回true
    
    
    //定义全局变量
    HashMap<String,List<int[]>> hm=new HashMap<String,List<int[]>>();
    /** Initialize your data structure here. */
    public MagicDictionary() {
        
    }
    
    /** Build a dictionary through a list of words */
    public void buildDict(String[] dict) {
        //对词典中的每个单词进行切分处理
        for(String word:dict){
            for(int i=0;i<word.length();i++){
                //将当前字母和剩下的字符串切开
                String key=word.substring(0,i)+word.substring(i+1);
                //将当前字母存入数组
                int [] pair=new int[]{i,word.charAt(i)};
                
                //获得映射数组的集合
                List<int []> val=hm.getOrDefault(key,new ArrayList<int []>());
                
                //将当前字母下标数组添加进集合
                val.add(pair);
                
                //存入Map
                hm.put(key,val);
            }
        }
    }
    
    /** Returns if there is any word in the trie that equals to the given word after modifying exactly one character */
    public boolean search(String word) {
        //对单词进行切分匹配,只要剩下的相同,当前字母不同,即返回true
        for(int i=0;i<word.length();i++){
            String key=word.substring(0,i)+word.substring(i+1);
            
            //如果存在相同的剩下字母串,则进行单个字母匹配,不同则true
            if(hm.containsKey(key)){
                
                //取出没有映射关系数组集合
                for(int [] pair:hm.get(key)){
                    
                    //位置相同,且字符不同
                    if(pair[0]==i&&pair[1]!=word.charAt(i)){
                        return true;
                    }
                }
            }
        }
        return false;
    }
}

/**
 * Your MagicDictionary object will be instantiated and called as such:
 * MagicDictionary obj = new MagicDictionary();
 * obj.buildDict(dict);
 * boolean param_2 = obj.search(word);
 */

分析2(List集合实现--运行时间比分析1快):

class MagicDictionary {
    //给定单词字典数组,和需要对比的单词,魔术数组的含义是:对比单词中只需要更改一个字符即可在字典数组中找到相同的单词
    //思路:将字典添加进行List集合(不存在重复的,直接使用list),之后对每个匹配单词进行匹配。如果只有一个不同且长度相同,则返回true,否则返回false。
    //分析:对字典数量小的适合,一旦字典数量大,时间复杂度显著下降
    List<String> dics;
    
    /** Initialize your data structure here. */
    public MagicDictionary() {
        dics=new ArrayList<String>();
    }
    
    /** Build a dictionary through a list of words */
    public void buildDict(String[] dict) {
        //将字典添加进集合
        for(String word:dict){
            dics.add(word);
        }
    }
    
    /** Returns if there is any word in the trie that equals to the given word after modifying exactly one character */
    public boolean search(String word) {
        //搜索整个词典
        for(String dic:dics){
            //如果长度不匹配,直接进行下一个查找
            if(word.length()!=dic.length()){
                continue;
            }else{
                //长度相同
                int diff=0,i=0;
                for(i=0;i<word.length();i++){
                    //查找不同的数量,如果不同大于1,则直接判别下一个
                    if(dic.charAt(i)!=word.charAt(i)){
                        diff++;
                        if(diff>1){
                            break;
                        }
                    }
                }
                if(i==word.length()&&diff==1){
                    //说明匹配完成,只有一个不同
                    return true;
                }
            }   
        }
        return false;
    }
}

/**
 * Your MagicDictionary object will be instantiated and called as such:
 * MagicDictionary obj = new MagicDictionary();
 * obj.buildDict(dict);
 * boolean param_2 = obj.search(word);
 */

分析3(原创--较分析1和分析2更快):

class MagicDictionary {
    //给定单词字典数组,和需要对比的单词,魔术数组的含义是:对比单词中只需要更改一个字符即可在字典数组中找到相同的单词
    //思路:由题意可知,只有一个字母不同,长度相同,所有使用Map存储数组长度相同作为key(类似字典的索引),使用List集合作为value,然后在list中查找是否只有一个不同的字母
    
    HashMap<Integer,List<String>> hm;
    
    /** Initialize your data structure here. */
    public MagicDictionary() {
        //初始化全局变量
        hm=new HashMap<Integer,List<String>>();
    }
    
    /** Build a dictionary through a list of words */
    public void buildDict(String[] dict) {
        //将字母长度相同的划分在一起
        for(String word:dict){
            int key=word.length();
            
            //初始化list集合
            List<String> list=hm.getOrDefault(key,new ArrayList<String>());
            
            list.add(word);
            
            hm.put(key,list);
        }
    }
    
    /** Returns if there is any word in the trie that equals to the given word after modifying exactly one character */
    public boolean search(String word) {
        //查找相同长度的部分,如果不存在则直接返回
        if(!hm.containsKey(word.length())){
            return false;
        }else{
            //说明包含相同长度的,则在该list中查找
            for(String s:hm.get(word.length())){
                int diff=0,i=0;
                for(i=0;i<word.length();i++){
                    if(s.charAt(i)!=word.charAt(i)){
                        diff++;
                        if(diff>1){
                            break;
                        }
                    }
                }
                //顺利匹配成功,只有一个不同的
                if(i==word.length()&&diff==1){
                    return true;
                }
            }
        }
        return false;
    }
}

/**
 * Your MagicDictionary object will be instantiated and called as such:
 * MagicDictionary obj = new MagicDictionary();
 * obj.buildDict(dict);
 * boolean param_2 = obj.search(word);
 */


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值