Word Search

Find a word hidden in a grid of letters, moving between side-by-side cells without reusing one.

Time O(rows · cols · 4ᴸ)Space O(L)Code C#
Watch it animatedStep through it, with the running line highlighted. Free with an account.

The idea

Try every cell as a starting point for the first letter. From a matching cell, mark it so it cannot be reused, then check its four neighbours for the next letter. If every neighbour fails, unmark the cell and let the caller try a different one.

Code

public static bool Exist(char[][] board, string word) {
    for (int r = 0; r < board.Length; r++)
        for (int c = 0; c < board[0].Length; c++)
            if (Dfs(board, word, r, c, 0)) return true;
    return false;
}

static bool Dfs(char[][] board, string word, int r, int c, int i) {
    if (i == word.Length) return true;
    if (r < 0 || c < 0 || r >= board.Length || c >= board[0].Length) return false;
    if (board[r][c] != word[i]) return false;
    char saved = board[r][c];
    board[r][c] = '#'; // mark visited
    bool found = Dfs(board, word, r + 1, c, i + 1) || Dfs(board, word, r - 1, c, i + 1) ||
                 Dfs(board, word, r, c + 1, i + 1) || Dfs(board, word, r, c - 1, i + 1);
    board[r][c] = saved; // backtrack
    return found;
}

Tips

In the .NET library

Mutating the board in place avoids a separate bool[,] visited array, but only works because the change is always undone before the function returns. Forgetting the restore line is a classic bug: later searches would see a board full of '#'.