79. Word Search
At a Glance
- Topic: backtracking
- Pattern: DFS / Backtracking
- Difficulty: Medium
- Companies: Amazon, Meta, Microsoft, Google, Apple
- Frequency: Very High
- LeetCode: 79
Problem (one-liner)
In a 2D grid of letters, determine if word exists as a path moving up/down/left/right using each cell at most once per path.
Recognition Cues
- Path in grid with visit once constraint
- Backtrack after failed branch — mark visited, recurse, unmark
- Word length × board size bounds search
Diagram
At-a-glance flow (replace with problem-specific Mermaid as you refine this note). camelCase node IDs; no spaces in IDs.
Loading diagram…
Approaches
- BFS per start — harder for full word (path state explosion).
- Optimal — DFS from each cell matching prefix —
O(n * m * 4^L)worst.
Optimal Solution
Go
func exist(board [][]byte, word string) bool {
rows := len(board)
cols := len(board[0])
var dfs func(row int, col int, position int) bool
dfs = func(row int, col int, position int) bool {
if position == len(word) {
return true
}
if row < 0 || col < 0 || row >= rows || col >= cols {
return false
}
if board[row][col] != word[position] {
return false
}
temp := board[row][col]
board[row][col] = '#'
found := dfs(row+1, col, position+1) ||
dfs(row-1, col, position+1) ||
dfs(row, col+1, position+1) ||
dfs(row, col-1, position+1)
board[row][col] = temp
return found
}
for row := 0; row < rows; row++ {
for col := 0; col < cols; col++ {
if dfs(row, col, 0) {
return true
}
}
}
return false
}JavaScript
function exist(board, word) {
const rows = board.length;
const cols = board[0].length;
function dfs(row, col, position) {
if (position === word.length) {
return true;
}
if (row < 0 || col < 0 || row >= rows || col >= cols) {
return false;
}
if (board[row][col] !== word[position]) {
return false;
}
const temp = board[row][col];
board[row][col] = '#';
const found =
dfs(row + 1, col, position + 1) ||
dfs(row - 1, col, position + 1) ||
dfs(row, col + 1, position + 1) ||
dfs(row, col - 1, position + 1);
board[row][col] = temp;
return found;
}
for (let row = 0; row < rows; row += 1) {
for (let col = 0; col < cols; col += 1) {
if (dfs(row, col, 0)) {
return true;
}
}
}
return false;
}Walkthrough
Board A B C, search AB. From (0,0) match A, DFS neighbors find B.
Invariant: Modified # marks current path; restored before returning so sibling branches see original letters.
Edge Cases
- Word longer than cells count — impossible
- Single-letter word
- Repeated letters — still one visit per path
Pitfalls
- Reusing a visited cell in same path — must mark
- Not restoring board — breaks other DFS roots
Similar Problems
- 46. Permutations — same DFS backtrack pattern in abstract form
- 131. Palindrome Partitioning — partition search instead of grid
Variants
- Word Search II — trie + DFS from each cell (batch queries)
Mind-Map Tags
#dfs #grid #backtracking #path #string
Last updated on
Spotted something unclear or wrong on this page?