676. Implement Magic Dictionary

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.









Todo : compare trade off 

Solution 1: 
Use trie 

Idea: build trie first and then do search , record the number of different chars 
, if the number of different chars > 1, return false already, 
If the number of different chars == 0 at the end , when it’s a word , return false 
If the number of different chars = 1 at the end of the word, return true

// other’s code 

Below is my accepted java code.
First build a trie tree, and in search(String word) function, we just edit every character from 'a' to 'z' and search the new string.
(This process is like "word ladder")

class MagicDictionary {
    class TrieNode {
        TrieNode[] children = new TrieNode[26];
        boolean isWord;
        public TrieNode() {}
    }
    TrieNode root;
    /** Initialize your data structure here. */
    public MagicDictionary() {
        root = new TrieNode();
    }
    
    /** Build a dictionary through a list of words */
    public void buildDict(String[] dict) {
        for (String s : dict) {
            TrieNode node = root;
            for (char c : s.toCharArray()) {
                if (node.children[c - 'a'] == null) {
                    node.children[c - 'a'] = new TrieNode();
                }
                node = node.children[c - 'a'];
            }
            node.isWord = true;
        }
    }
    
    /** 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) {
        char[] arr = word.toCharArray();
        for (int i = 0; i < word.length(); i++) {
            for (char c = 'a'; c <= 'z'; c++) {
                if (arr[i] == c) {
                    continue;
                }
                char org = arr[i];
                arr[i] = c;
                if (helper(new String(arr), root)) {
                    return true;
                }
                arr[i] = org;
            }
        }
        return false;
    }
    public boolean helper(String s, TrieNode root) {
        TrieNode node = root;
        for (char c : s.toCharArray()) {
            if (node.children[c - 'a'] == null) {
                return false;
            }
            node = node.children[c - 'a'];
        }
        return node.isWord;
    }
}














Solution 2 : bucket by length 
Use. A HashMap to store key : length of a word , value: the words of the length 

When check if a word A is one char from the word in the HashMap, first get the list of words 
Sharing the same length , and then check one by one at each chars, if the number of different chats == 1 , return true, else return false 




class MagicDictionary {
    HashMap<Integer, List<String>> map;

    /** Initialize your data structure here. */
    public MagicDictionary() {
        map = new HashMap();
        
        
    }
    
    /** Build a dictionary through a list of words */
    public void buildDict(String[] dict) {
        for(String word : dict){
            if(!map.containsKey(word.length())){
                map.put(word.length(), new ArrayList<>());
            }
            map.get(word.length()).add(word);
            //  buckets.computeIfAbsent(word.length(), x -> new ArrayList()).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) {
        if(!map.containsKey(word.length())) return false;
        for(String candidate : map.get(word.length())){
            int mismatch = 0;
            for(int i = 0; i < word.length(); i++){
                if(word.charAt(i) != candidate.charAt(i)) mismatch++;
                if(mismatch > 1) break;
            }
            if(mismatch == 1) return true;
        }
        return false;
    }
}

 

posted on 2018-11-06 10:09  猪猪&#128055;  阅读(132)  评论(0)    收藏  举报

导航