medium

Word Search

Check whether a word can be traced through neighboring letters in a grid.

1. Define the problem

Word Search

Given an m x n grid of characters board and a string word, return true if word exists in the grid. The word must be constructed from letters of sequentially adjacent cells, where adjacent cells are horizontally or vertically neighboring. The same cell may not be used more than once in one word. Use backtracking that steps into a matching neighbor, temporarily marks that cell visited so the same path can't reuse it, and undoes the mark on the way back out so a different path can use that cell.

Constraints

  • m == board.length
  • n == boardi.length
  • 1 ≤ m, n ≤ 6
  • 1 ≤ word.length ≤ 15
  • board and word consist of only lowercase and uppercase English letters

Example

Inputboard = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"
Outputtrue

Explanation Starting at the top-left A, the path A → B → C → C → E → D visits six adjacent cells in order without reusing any of them.

2. Know the words first

In plain terms

Adjacent
Directly next to a cell — up, down, left, or right, but never diagonally.
3. Visualize the solution

Step into a matching neighbor, mark it visited, undo on the way back out

Step into a matching neighbor, mark it visited, undo on the way back out
Statustry

Start at (0,0)="A", matches word[0]. Mark visited, look for "B" next.

What happens in this step

path so far: (0,0)='A'
call: backtrack(0, 0, 0)

board[0][0]='A' matches word[0]='A'. The cell is temporarily marked '#' (visited) and backtrack tries its neighbors in order down, up, right, left, looking for word[1]='B'.
Step 1 of 6

Steps to visualize

  1. Start a search from every cell that matches the first letter of the word.
  2. If the current cell matches the next letter, mark it visited and try each of its unvisited neighbors for the letter after that.
  3. If a mismatch or a dead end is hit, undo the visited mark on this cell and report failure up to the caller.
  4. The word is found the moment every letter has been matched along one connected path.
4. Walk through the code

Walk through the code

Same walkthrough, now with the code. Press Next to move one step and watch which lines run.

Step into a matching neighbor, mark it visited, undo on the way back out
Statustry

Start at (0,0)="A", matches word[0]. Mark visited, look for "B" next.

What happens in this step

path so far: (0,0)='A'
call: backtrack(0, 0, 0)

board[0][0]='A' matches word[0]='A'. The cell is temporarily marked '#' (visited) and backtrack tries its neighbors in order down, up, right, left, looking for word[1]='B'.
Step 1 of 6
5. Solution

Solution

solution.tsTypeScript
function exist(board, word) {
  const rows = board.length;
  const cols = board[0].length;

  function backtrack(row, col, index) {
    if (index === word.length) {
      return true;
    }
    if (row < 0 || row >= rows || col < 0 || col >= cols) {
      return false;
    }
    if (board[row][col] !== word[index]) {
      return false;
    }

    const temp = board[row][col];
    board[row][col] = '#';

    const found =
      backtrack(row + 1, col, index + 1) ||
      backtrack(row - 1, col, index + 1) ||
      backtrack(row, col + 1, index + 1) ||
      backtrack(row, col - 1, index + 1);

    board[row][col] = temp;

    return found;
  }

  for (let row = 0; row < rows; row++) {
    for (let col = 0; col < cols; col++) {
      if (backtrack(row, col, 0)) {
        return true;
      }
    }
  }

  return false;
}
Time
O(m · n · 4^L)
Space
O(L)
6. Test cases

Test cases

InputExpectedCovers
board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"trueexample from the docstring
board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "SEE"truea shorter word found along a different path
board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCB"falsethe only path would need to reuse a cell, which is not allowed
board = [["a"]], word = "a"truesmallest valid board, a single matching cell
board = [["a"]], word = "b"falsesmallest board, no match at all
board = [["a","a"]], word = "aa"truetwo adjacent identical letters form the word
board = [["a","b"],["c","d"]], word = "abcd"falseletters exist on the board but no adjacent path connects them in order