An interactive visualization of the Add and Search Words data structure. Watch how a Trie supports addWord insertions and search queries with the '.' wildcard character, which matches any letter via DFS branching.
Trie LeetCode 211 ↗ Medium. acts as a wildcard matching any single character.WordDictionary class:WordDictionary() — Initializes the data structure.addWord(word) — Adds word to the data structure. It can be matched later.search(word) — Returns true if any previously added word matches word. The character . matches any letter."bad", "dad", "mad", searching ".ad" returns true (matches all three), and searching "b.a" returns false.
class WordDictionary { val root = HashMap<Char, Any>() fun addWord(word: String) { var node = root for (ch in word) { node = node.getOrPut(ch) { HashMap<Char,Any>() } as HashMap<Char,Any> } ; node['#'] = true } fun search(word: String): Boolean { fun dfs(node: HashMap<Char,Any>, i: Int): Boolean { if (i == word.length) { return '#' in node } if (word[i] == '.') { for (child in node.keys) { if (child != '#' && dfs(node[child] as HashMap<Char,Any>, i + 1)) return true } ; return false } if (word[i] !in node) return false return dfs(node[word[i]]!! as HashMap<Char,Any>, i + 1) } return dfs(root, 0) }}
A Trie (prefix tree) stores words character by character, sharing common prefixes. Each node is a dictionary
mapping characters to child nodes. An end-of-word marker ('#') signals that a complete word terminates at that node.
For wildcard search, the . character triggers DFS across all children simultaneously, exploring every
possible branch.
Starting from the root, traverse the trie character by character. If a character's child node doesn't exist, create it.
After processing all characters, mark the final node with '#' = True to indicate a complete word.
This is a standard trie insertion in O(L) time where L is the word length.
The search uses DFS (depth-first search). For each character position:
i == len(word)), check if the current node has the end-of-word marker '#'.'#'). If any recursive call returns True, the search succeeds. This is where branching happens — multiple paths are explored.False.
When searching ".ad" in a trie containing "bad", "dad", and "mad",
the wildcard at position 0 causes the algorithm to explore all three branches (b, d, m)
simultaneously. Each branch then continues matching "ad". All three branches succeed, so the search returns True
as soon as the first successful branch is found.
The addWord operation is always O(L). The search operation is O(L) for exact matches,
but each '.' wildcard multiplies the work by up to 26 (the number of possible child branches).
In the worst case with all wildcards, this becomes O(26^L), but in practice the trie's structure prunes most branches early.