Given a character board and a list of words, return all words found
by walking adjacent cells without reusing a cell in one word.
Hidden answer: pruning, visited state, and Python solution
Build a trie so DFS can stop as soon as a prefix is impossible. The
visited mark belongs to the current path only, so restore the board
cell after recursion. Store the full word at terminal trie nodes to
avoid rebuilding strings and set it to None after
finding it to prevent duplicates.
def find_words(board, words):
root = {}
END = "#"
for word in words:
node = root
for ch in word:
node = node.setdefault(ch, {})
node[END] = word
rows, cols = len(board), len(board[0])
found = []
def dfs(r, c, node):
ch = board[r][c]
if ch not in node:
return
nxt = node[ch]
word = nxt.pop(END, None)
if word is not None:
found.append(word)
board[r][c] = "*"
for dr, dc in ((1, 0), (-1, 0), (0, 1), (0, -1)):
nr, nc = r + dr, c + dc
if 0 <= nr < rows and 0 <= nc < cols and board[nr][nc] != "*":
dfs(nr, nc, nxt)
board[r][c] = ch
if not nxt:
node.pop(ch)
for r in range(rows):
for c in range(cols):
dfs(r, c, root)
return found