Word Search

medium backtracking grid dfs

Problem

Given an m x n grid of characters board and a string word, return true if word exists in the grid. The word can be constructed from letters of sequentially adjacent cells, where adjacent cells are horizontally or vertically neighboring. The same letter cell may not be used more than once.

Try every cell as a starting point. From there, DFS: if the current letter matches word[k], mark the cell visited (overwrite with '#'), recurse into the four neighbours with k + 1, restore the letter on unwind, and short-circuit on success. Reaching k == len(word) means the trace is complete.

Inputgrid = [[A,B,C,E],[S,F,C,S],[A,D,E,E]], word = "ABCCED"
Outputtrue
Trace: (0,0)→(0,1)→(0,2)→(1,2)→(2,2)→(2,1).

def exist(grid, word):
    R, C = len(grid), len(grid[0])
    def dfs(r, c, k):
        if k == len(word): return True
        if r < 0 or r >= R or c < 0 or c >= C or grid[r][c] != word[k]:
            return False
        ch = grid[r][c]; grid[r][c] = "#"
        ok = (dfs(r + 1, c, k + 1) or dfs(r - 1, c, k + 1)
              or dfs(r, c + 1, k + 1) or dfs(r, c - 1, k + 1))
        grid[r][c] = ch
        return ok
    for r in range(R):
        for c in range(C):
            if dfs(r, c, 0): return True
    return False
function exist(grid, word) {
  const R = grid.length, C = grid[0].length;
  function dfs(r, c, k) {
    if (k === word.length) return true;
    if (r < 0 || r >= R || c < 0 || c >= C || grid[r][c] !== word[k]) return false;
    const ch = grid[r][c]; grid[r][c] = "#";
    const ok = dfs(r + 1, c, k + 1) || dfs(r - 1, c, k + 1)
            || dfs(r, c + 1, k + 1) || dfs(r, c - 1, k + 1);
    grid[r][c] = ch;
    return ok;
  }
  for (let r = 0; r < R; r++)
    for (let c = 0; c < C; c++)
      if (dfs(r, c, 0)) return true;
  return false;
}
char[][] g; String w; int R, C;
public boolean exist(char[][] grid, String word) {
    g = grid; w = word; R = grid.length; C = grid[0].length;
    for (int r = 0; r < R; r++)
        for (int c = 0; c < C; c++)
            if (dfs(r, c, 0)) return true;
    return false;
}
boolean dfs(int r, int c, int k) {
    if (k == w.length()) return true;
    if (r < 0 || r >= R || c < 0 || c >= C || g[r][c] != w.charAt(k)) return false;
    char ch = g[r][c]; g[r][c] = '#';
    boolean ok = dfs(r + 1, c, k + 1) || dfs(r - 1, c, k + 1)
              || dfs(r, c + 1, k + 1) || dfs(r, c - 1, k + 1);
    g[r][c] = ch;
    return ok;
}
int R, C;
bool dfs(vector<vector<char>>& g, string& w, int r, int c, int k) {
    if (k == (int)w.size()) return true;
    if (r < 0 || r >= R || c < 0 || c >= C || g[r][c] != w[k]) return false;
    char ch = g[r][c]; g[r][c] = '#';
    bool ok = dfs(g, w, r + 1, c, k + 1) || dfs(g, w, r - 1, c, k + 1)
           || dfs(g, w, r, c + 1, k + 1) || dfs(g, w, r, c - 1, k + 1);
    g[r][c] = ch;
    return ok;
}
bool exist(vector<vector<char>>& g, string w) {
    R = g.size(); C = g[0].size();
    for (int r = 0; r < R; r++)
        for (int c = 0; c < C; c++)
            if (dfs(g, w, r, c, 0)) return true;
    return false;
}
Time: O(R · C · 4^L) Space: O(L) recursion