InterviewPrepKit

Home / Coding / Tries

Word Search II

hard Original ↗
Solving tips
  • Key insight: with up to 3*10^4 words but a tiny board, never search per word; put all words in a trie and run one backtracking DFS per cell, advancing a trie pointer in lockstep.
  • A dead trie child instantly kills every word sharing that prefix; store the full word on its end node so you can emit without path bookkeeping.
  • Mark cells visited (e.g. '#') and un-mark on backtrack, and set node.word=None (or use a set) after emitting to avoid duplicates.
  • Time O(m*n * 4 * 3^(L-1)) with L<=10, O(total chars) space; prune exhausted branches (delete childless, word-less nodes) to avoid TLE on adversarial inputs.

Problem

You are given an m x n grid of lowercase letters and a list of words. Return every word from the list that can be spelled by starting at some cell and repeatedly stepping to a horizontally or vertically adjacent cell, reading one letter per cell. A single spelling may not visit the same cell twice, but different words (and different attempts) are independent. Return each found word once, in any order.

Examples

  • Board [["a","b"],["c","d"]], words ["abdc","bd","acb"]["abdc","bd"]. "abdc" traces a(0,0) → b(0,1) → d(1,1) → c(1,0); "bd" traces b(0,1) → d(1,1); "acb" fails because c(1,0) and b(0,1) are diagonal, not adjacent.
  • Board [["o","a","a","n"],["e","t","a","e"],["i","h","k","r"],["i","f","l","v"]], words ["oath","pea","eat","rain"]["eat","oath"]. "eat" runs e(1,3) → a(1,2) → t(1,1); "pea" and "rain" have no valid path (no p at all; rain’s letters aren’t connected).
  • Board [["a","a"]], words ["aaa"][]. Only two cells exist and a cell cannot be reused within one spelling.

Constraints

  • 1 <= m, n <= 12 — the board has at most 144 cells.
  • 1 <= len(words) <= 3 * 10^4, with 1 <= len(words[i]) <= 10; all letters lowercase.
  • All words in the list are distinct.

The huge word count against a tiny board is the whole problem: anything that searches the board once per word is fighting the constraints.

Think about it first

Hint 1 You already know how to check one word with backtracking DFS (Word Search I). What is the total cost of repeating that for 3 * 10^4 words?
Hint 2 Many words share prefixes, and a DFS path spells out a prefix letter by letter. If no word starts with the letters spelled so far, every word dies on that path at once — so check all words simultaneously.
Hint 3 Put all the words in a trie and run one backtracking DFS from each cell, moving a trie pointer alongside the board pointer: step to a neighbor only if the trie has that child, and emit a word whenever the current node marks an end. Removing found words / dead leaves from the trie as you go keeps later searches fast.
Your workspace Not runnable by design — this is your interview scratchpad. Saved on this device.