Simple JS Solution w/ Comments - Trie
\n/**\n * *Time: O(M) - well defined words, words wihtout ...\n * *Time: O(N x 26^M) - N = number of keys and 26^M for undefined words\n * *Space: O(1) - well d
```\n/**\n * *Time: O(M) - well defined words, words wihtout ...\n * *Time: O(N x 26^M) - N = number of keys and 26^M for undefined words\n * *Space: O(1) - well defined words\n * *Space: O(M) - undefined words\n */\n// Runtime: 2153 ms, faster than 32.71% of JavaScript online submissions for Design Add and Search Words Data Structure.\n// Memory Usage: 99.1 MB, less than 25.69% of JavaScript online submissions for Design Add and Search Words Data Structure.\nclass WordDictionary {\n  constructor() {\n    this.root = {};\n  }\n\n  addWord(word) {\n    let node = this.root;\n\n    for (const char of word) {\n      if (!node[char]) node[char] = {};\n\n      node = node[char];\n    }\n\n    node.isEnd = true;\n  }\n\n  search(word) {\n    const traverse = (node, i) => {\n      const char = word[i];\n\n      // reached end of word, check if word exists\n      if (i === word.length) return node.isEnd || false;\n\n      // if wildcard, iterate every possible keys and check if word exists\n      // if valid char exist, recursively check if other characters of the word exist\n      // else return false\n      if (char == \'.\') {\n        for (const key in node) {\n          if (traverse(node[key], i + 1)) return true;\n        }\n      } else if (node[char]) return traverse(node[char], i + 1);\n\n      return false;\n    };\n\n    return traverse(this.root, 0);\n  }\n}\n\n```
['Depth-First Search', 'Trie', 'JavaScript']