Java DFS + Trie, extendable for modifying n characters
\nclass MagicDictionary {\n    \n    class TrieNode {\n        Map<Character, TrieNode> children = new HashMap<>();\n        boolean isEnd = false;\n    }\n    
```\nclass MagicDictionary {\n    \n    class TrieNode {\n        Map<Character, TrieNode> children = new HashMap<>();\n        boolean isEnd = false;\n    }\n    \n    public TrieNode root;\n\n    public MagicDictionary() {\n        this.root = new TrieNode();    \n    }\n    \n    //build a regular trie\n    public void buildDict(String[] dictionary) {\n        for (String s: dictionary) {\n            TrieNode node = this.root;\n            for (char c : s.toCharArray()) {\n                if (!node.children.containsKey(c)) {\n                    node.children.put(c, new TrieNode());\n                }\n                node = node.children.get(c);\n            }\n            node.isEnd = true;\n        }\n    }\n    \n    public boolean search(String searchWord) {\n        TrieNode node = this.root;\n        //alter exact 1 char, so put 1\n        return magicSearch(searchWord, node, 1);\n    }\n    \n    public boolean magicSearch(String searchWord, TrieNode node, int diff) {\n        if (diff == 0) {\n            return strictSearch(node, searchWord);\n        }\n        \n        char[] searchWordArray = searchWord.toCharArray();\n        for (int i = 0; i<searchWordArray.length; i++) {\n            char c = searchWordArray[i];\n            \n            //Option 1: change the current char\n            for (char alter : node.children.keySet()) {\n                if (alter != c) {\n                    if (magicSearch(searchWord.substring(i+1), node.children.get(alter), diff - 1)) {\n                        return true;\n                    }\n                }    \n            }\n            \n            //Option 2: do not change the current char\n            if (!node.children.containsKey(c)) {\n                break; // return false if we can\'t change the current char but but the char does not belong to the node\'s children\n            } \n            \n            node = node.children.get(c);\n        }\n        return false;\n    }\n    \n    public boolean strictSearch(TrieNode node, String word) {\n        for (char c: word.toCharArray()) {\n            if (!node.children.containsKey(c)) {\n                return false;\n            } \n            node = node.children.get(c);\n        }\n        return node.isEnd;\n    }\n}\n```
['Depth-First Search', 'Trie', 'Recursion', 'Java']