Bird
Raised Fist0
Interview PrepbacktrackinghardAmazonFacebookGoogleBloomberg

Word Search II (Trie + Backtrack)

Choose your preparation mode3 modes available
Steps
setup

Build Trie - insert 'eat'

Insert word 'eat' into the trie. Root → e(id=1) → a(id=2) → t(id=3, word='eat'). Three nodes created along the path.

💡 The trie stores all search words as paths from root. Each character gets its own node.
Line:for w in words: node = root for c in w: if c not in node.children: node.children[c] = TrieNode() node = node.children[c] node.word = w
💡 Inserting 'eat' creates nodes for e→a→t with word='eat' at the leaf.
📊
Word Search II - Watch the Trie + Backtracking Execute, Step by Step
The trie acts as a combined dictionary and prefix checker - instead of checking all words per cell, we follow one trie path that matches the board. When the trie has no child for a board character we prune immediately.
Step 1/11
·Active fillAnswer cell
insert
eat
eat*
insert
oath
eoath*
search
t
Search: false
search
e
e
search
ea
ea
search
e
e
search
eat
eat*
Pairs found: 1
Search: true
search
o
o
Pairs found: 1
search
oa
oa
Pairs found: 1
search
oat
oat
Pairs found: 1
find_pairs
oath
oh*
Pairs found: 2
Search: true

Key Takeaways

Building a trie from all words allows prefix-based pruning - if no word starts with a board character the DFS is skipped entirely.

Without a trie you'd check each word against each board path separately, which is much slower.

Marking cells '#' during DFS prevents revisiting the same cell in one path, ensuring valid board paths only.

The restore step (board[r][c] = letter) after backtracking lets other DFS paths reuse the cell.

Pruning trie nodes with no children after finding a word avoids re-finding the same word and shrinks future search space.

This optimization is subtle but powerful - the trie gets smaller as words are found.