Word Search II
Master this topic with zero to advance depth.
Word Search II
The Challenge of Multiple Words
If we have words, running a standard Word Search (DFS) for each word takes . This is inefficient because many words share prefixes (e.g., 'apple' and 'apply').
Trie for Prefix Sharing
By storing the dictionary in a Trie, we can search for all words simultaneously. As we traverse the grid in DFS, we also traverse the Trie. If a path in the grid doesn't match any prefix in the Trie, we prune the search immediately.
Optimization: Trie Pruning
Once a word is found, we can remove it from the Trie (or mark it as found) and potentially delete leaf nodes that are no longer part of any other words. This drastically reduces the search space for subsequent cells.
Given an m x n board of characters and a list of strings words, return all words on the board.
Each word must be constructed from letters of sequentially adjacent cells, where adjacent cells are horizontally or vertically neighboring. Includes visual Trie-based pruning trace. The same letter cell may not be used more than once in a word.
Examples
Level I: Naive DFS (Multiple Word searches)
Intuition
Iterate through each word in the list and perform a standard DFS search on the board.
For each word in words, scan every cell (r, c). If board[r][c] == word[0], start a DFS to find the rest of the characters.
Detailed Dry Run
Searching 'oath'. Find 'o' at (0,0). Neighbors: (0,1) 'a'. Next: (1,1) 't'. Next (0,1) NO, (0,2) NO, (1,0) NO... SUCCESS.
Level II: Backtracking with Trie
Intuition
Insert all words into a Trie. Traverse the board and the Trie simultaneously to find matches.
Starting at each cell, if the character exists as a child of the Trie root, move into the Trie. If node.isEndOfWord, add the word to result.
Detailed Dry Run
Trie: root -> o -> a -> t -> h (END). At (0,0) 'o': matches root.child('o'). Neighbors of (0,0): 'a' at (0,1) matches 'o'.child('a'). Neighbors of (0,1): 't' at (1,1) matches 'a'.child('t')...
Level III: Optimized Trie (Node Removal)
Intuition
When a leaf node is found and its word is extracted, if it has no children, we can delete the node from its parent to avoid re-visiting dead branches.
Add a parent pointer or count to each node. When word != "", set it to null. If children count becomes 0, remove the entry from search path completely.
Detailed Dry Run
Trie: root -> o -> a -> t -> h (END). After finding 'oath', the path 'h' -> 't' -> 'a' -> 'o' is pruned if no other words use them. Subsequent board scans will skip 'o' immediately.
Found an issue or have a suggestion?
Help us improve! Report bugs or suggest new features on our Telegram group.