Home
DSA Patterns
Trie
Design Add and Search Words Data Structure
Design Add and Search Words Data Structure
Store words in a trie and search them with '.' wildcards using a DFS that branches at every dot.
Problem Understanding
Design a WordDictionary with two operations:
addWord(word)stores a word.search(word)returnstrueif any stored word matches, where'.'in the pattern matches any one letter.
Example: after adding bad, dad and mad, search("pad") is false, search("bad") is true, search(".ad") is true and search("b..") is true.
The Intuition: A Trie, and a DFS for the Dots
addWord is the ordinary trie insert. The new part is search.
For a normal letter there is exactly one child to follow. For '.' there may be several, and you do not know which one leads to a match, so try them all: a DFS over (node, index).
- If
indexreaches the end of the pattern, return whether this node ends a word. - If the character is a letter, follow that child, or fail if it is missing.
- If it is
'.', try every child withindex + 1and returntrueas soon as one succeeds.
Interactive Walkthrough
Words are added first, then each search walks the trie. The branch being followed is outlined; at a '.', watch the search try one child, back up out of it if it fails, and move on to the next.
Dry Run Table
Stored: bat, bed. Search: b.d
| Index | Pattern | Node | Action |
|---|---|---|---|
| 0 | b |
root | follow b |
| 1 | . |
b |
try child a |
| 2 | d |
a |
no d child: back up |
| 1 | . |
b |
try child e |
| 2 | d |
e |
follow d |
| 3 | end | d |
ends a word: true |
The Solution Template
A trie with a DFS search that branches at every '.'.
Design Add and Search Words Data Structure Code
1class WordDictionary {2 constructor() {3 this.root = {};4 }56 addWord(word) {7 let node = this.root;8 for (const ch of word) {9 node = node[ch] ??= {};10 }11 node.$ = true;12 }1314 search(word) {15 const dfs = (node, i) => {16 if (i === word.length) return node.$ === true;17 const ch = word[i];18 if (ch === '.') {19 return Object.keys(node).some((key) => key !== '$' && dfs(node[key], i + 1));20 }21 return node[ch] !== undefined && dfs(node[ch], i + 1);22 };23 return dfs(this.root, 0);24 }25}
Edge Cases & Common Mistakes
- A prefix is not a word: with only
atstored,search("a")isfalse. Check the word-end flag at the end of the pattern, not just that the path exists. - Returning after the first child at a
'.': the first branch may fail while a later one matches; keep trying until one succeeds. - A pattern longer than every word: the walk runs out of children and fails; no special case is needed.
- All dots:
search("...")is true if any stored word has exactly three letters.
Summary
Add and Search Words is a trie plus one idea: a '.' is a branch point, so search becomes a DFS that tries each child there and backs up from dead ends. Letters follow a single child, and the end of the pattern checks the word-end flag.
More practice: DSA interview questions with answers · patterns cheat sheet
