JAVA程序设计:实现一个魔法字典(LeetCode:676)

实现一个带有buildDict, 以及 search方法的魔法字典。

对于buildDict方法,你将被给定一串不重复的单词来构建一个字典。

对于search方法,你将被给定一个单词,并且判定能否只将这个单词中一个字母换成另一个字母,使得所形成的新单词存在于你构建的字典中。

示例 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
注意:

你可以假设所有输入都是小写字母 a-z。
为了便于竞赛,测试所用的数据量很小。你可以在竞赛结束后,考虑更高效的算法。
请记住重置MagicDictionary类中声明的类变量,因为静态/类变量会在多个测试用例中保留。 请参阅这里了解更多详情。

思路:方法一:暴力求汉明距离

class MagicDictionary {

	List<String> list;
    /** Initialize your data structure here. */
    public MagicDictionary() {
        list=new ArrayList<>();
    }	
    
    /** Build a dictionary through a list of words */
    public void buildDict(String[] dict) {
        for(int i=0;i<dict.length;i++)
        	list.add(dict[i]);
    }
    
    /** 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(int i=0;i<list.size();i++) {
        	int d=0;
        	if(word.length()!=list.get(i).length())
        		continue;
        	for(int j=0;j<word.length();j++) {
        		if(word.charAt(j)!=list.get(i).charAt(j))
        			d++;
        		if(d>1) break;
        	}
        	if(d==1) return true;
        }
        return false;
    }
}

方法二:广义邻居。

回想一下,在方法 1 中,如果一个单词中只有一个字符可以更改以使字符串相等,那么两个单词就是邻居。

让我们假设一个词 “apple” 具有广义邻居 “pple”、“aple”、“aple”、“appe” 和 “appl”。在搜索像 apply 这样的词是否有像 apple 这样的邻居时,我们只需要知道它们是否有一个广义邻居。

继续上述思考,一个问题是 “apply” 不是自身的邻居,而是具有相同的广义邻居 “*pply”。为了解决这个问题,我们将计算生成 “*pply” 的源的数量。如果有 2 个或更多,则其中一个不会是 “apply”。如果只有一个,我们应该检查它不是 “apply”。无论是哪种情况,我们都可以确定有一些神奇的单词生成了 “*pply”,而不是 “apply”。

class MagicDictionary {

	Set<String> st;
	Map<String,Integer> map;
    /** Initialize your data structure here. */
    public MagicDictionary() {
        st=new HashSet<>();
        map=new HashMap<>();
    }	
    
    public ArrayList<String> generalizedNeighbors(String word){
    	ArrayList<String> ans=new ArrayList<>();
    	char[] ca=word.toCharArray();
    	for(int i=0;i<word.length();i++) {
    		char letter=ca[i];
    		ca[i]='*';
    		String magic=new String(ca);
    		ans.add(magic);
    		ca[i]=letter;
    	}
    	return ans;
    }
    /** Build a dictionary through a list of words */
    public void buildDict(String[] dict) {
        for(String word : dict) {
        	st.add(word);
        	for(String nei : generalizedNeighbors(word)) {
        		map.put(nei, map.getOrDefault(nei, 0)+1);
        	}
       }
    }
    
    /** 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 nei : generalizedNeighbors(word)) {
    		int c=map.getOrDefault(nei, 0);
    		if(c>1 || c==1 && !st.contains(word)) return true;
    	}
        return false;
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值