Efficient Trie and Java 8 w/ Explanation
The implementation is a simple Trie, with the method relaxedSearch.\n\nrelaxedSearch searches for a word, with one deviation from a normal trie.\n\nIf there is 
The implementation is a simple Trie, with the method relaxedSearch.\n\nrelaxedSearch searches for a word, with one deviation from a normal trie.\n\nIf there is a match with the current character, it proceeds as usual in that branch.\nBut for all the non matched characters, it still continues searching, by incrementing the changedTimes variable, which maintains how many times a character was changed in the word search from the root.\n\n\nAny search that involves changedTimes > 1, is immediately terminated by returning false as we are allowed to change only one character.\n\nThe solution is reached, when we find word in the trie and the changedTimes is exactly == 1.\n```\nclass MagicDictionary {\n\n        Trie trie;\n        public MagicDictionary() {\n            trie = new Trie(256);\n        }\n\n        public void buildDict(String[] dict) {\n            Arrays.stream(dict).forEach(s -> trie.insert(s));\n        }\n\n        public boolean search(String word) {\n            return trie.relaxedSearch(word);\n        }\n\n        class Trie {\n            private int R;\n            private TrieNode root;\n\n            public Trie(int R) {\n                this.R = R;\n                root = new TrieNode();\n            }\n            \n            public boolean relaxedSearch(String word) {\n                return relaxedSearch(root, word, 0);\n            }\n\n            private boolean relaxedSearch(TrieNode root, String word, int changedTimes) {\n                if (root == null || (!root.isWord && word.isEmpty()) || changedTimes > 1) return false;\n                if (root.isWord && word.isEmpty()) return changedTimes == 1;\n                return Arrays.stream(root.next).anyMatch(nextNode -> relaxedSearch(nextNode, word.substring(1),\n                        root.next[word.charAt(0)] == nextNode ? changedTimes : changedTimes+1));\n            }\n\n            // Inserts a word into the trie.\n            public void insert(String word) {\n                insert(root, word);\n            }\n\n            private void insert(TrieNode root, String word) {\n                if (word.isEmpty()) { root.isWord = true; return; }\n                if (root.next[word.charAt(0)] == null) root.next[word.charAt(0)] = new TrieNode();\n                insert(root.next[word.charAt(0)], word.substring(1));\n            }\n\n            private class TrieNode {\n                private TrieNode[] next = new TrieNode[R];\n                private boolean isWord;\n            }\n\n        }\n    }\n```
[]