Practice LeetCode 79 · Word Search · GFG · Word Search in Grid
RecursionBacktrackingGrid DFSVisited

Word Search · Grid Backtracking

Trace a word through a grid, moving to adjacent cells, never reusing one. DFS follows a promising path letter by letter and backtracks the instant the next character doesn't match.

DFS with a visited mark

From each cell matching the first letter, DFS into the 4 neighbors seeking the next letter. Temporarily mark the cell used (so the path can't cross itself), recurse, then unmark on the way back.

Prune the instant it breaks

  • Out of bounds → fail this branch
  • Cell letter ≠ needed letter → fail
  • Cell already on the path → fail
  • Matched all letters → word found

Trace the word

Untouched On path Current Dead end Found
slowfast
Step 0
Matched
0
Path length
0
Backtracks
0
Found?
?

C++

bool dfs(vector<vector<char>>& b, int r, int c,
         string& word, int k) {
    if (k == word.size()) return true;   // all letters matched
    if (r < 0 || c < 0 || r >= b.size() || c >= b[0].size())
        return false;               // off the grid
    if (b[r][c] != word[k]) return false;  // wrong letter

    char tmp = b[r][c];
    b[r][c] = '#';                    // mark visited
    bool found = dfs(b, r+1, c, word, k+1) ||
                 dfs(b, r-1, c, word, k+1) ||
                 dfs(b, r, c+1, word, k+1) ||
                 dfs(b, r, c-1, word, k+1);
    b[r][c] = tmp;                     // UNMARK (backtrack)
    return found;
}

bool exist(vector<vector<char>>& b, string word) {
    for (int r = 0; r < b.size(); r++)
        for (int c = 0; c < b[0].size(); c++)
            if (dfs(b, r, c, word, 0)) return true;
    return false;
}
Time
O(m·n·4ᴸ)

Every cell as a start, 4 directions per step, word length L.

Space
O(L)

Recursion depth equals the word length.

Prune
letter ≠

Mismatch kills a branch immediately, that's what tames the 4ᴸ.

  • Mark then unmark is the whole trick: '#' blocks revisiting during this path, and restoring it lets other paths reuse the cell.
  • The letter-match check acts as a free prune, most branches die on the first wrong character.
  • Mutating the grid in place avoids a separate visited matrix; just remember to restore it.
  • For many words (LC 212, Word Search II), build a Trie so all words share one DFS pass.
  • Same 4-directional grid DFS powers number-of-islands and flood fill, minus the letter constraint.