✨ JavaScript - Clean Solution Using Trie
\nvar MagicDictionary = function() {\n  this.trie = {\n    children: {}, \n  }\n};\n\n/** \n * @param {string[]} dictionary\n * @return {void}\n */\nMagicDictio
```\nvar MagicDictionary = function() {\n  this.trie = {\n    children: {}, \n  }\n};\n\n/** \n * @param {string[]} dictionary\n * @return {void}\n */\nMagicDictionary.prototype.buildDict = function(dictionary) {\n  dictionary.forEach(word => {\n    let current = this.trie\n\n    ;[...word].forEach((char, index, { length }) => {\n      const node = current.children[char] ?? { children: {} }\n      current.children[char] = node\n\n      const isEnd = index === length - 1\n      if (isEnd) node.isEnd = true\n      \n      current = node\n    })\n  })\n};\n\n/** \n * @param {string} searchWord\n * @return {boolean}\n */\nMagicDictionary.prototype.search = function(searchWord) {\n  const dfs = (index, trie, isChanged) => {\n    if (index === searchWord.length) {\n      return trie?.isEnd && isChanged\n    }\n    \n    return Object.keys(trie.children)\n      .some((key) => {\n        const isSame = key === searchWord[index]\n        if (isChanged && !isSame) return false\n\n        return dfs(\n          index + 1, \n          trie.children[key], \n          isChanged || !isSame\n        )\n      })\n  }\n\n  return dfs(0, this.trie, false)\n}; \n```
['Tree', 'Depth-First Search', 'Trie', 'Recursion', 'JavaScript']