39. 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 can be constructed from letters of sequentially adjacent cells (horizontally or vertically). The same cell may not be used more than once.
Examples:
Input: board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"
Output: true
Input: board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "SEE"
Output: true
Input: board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCB"
Output: falseProblem Breakdown:
- Try starting the search from every cell in the grid. If any starting position finds the word, return true.
for i in range(len(board)): for j in range(len(board[0])): if backtrack(board, word, i, j, 0): return True return False- The backtracking function checks: are we out of bounds? Does the current cell match the current character in the word? Have we matched all characters?
def backtrack(board, word, i, j, k): if k == len(word): return True if i < 0 or i >= len(board) or j < 0 or j >= len(board[0]) or board[i][j] != word[k]: return False- Mark the current cell as visited (temporarily modify it) to prevent revisiting during the current path.
temp = board[i][j] board[i][j] = '#'- Recursively explore all four directions. If any direction finds the rest of the word, return true. Otherwise, restore the cell and backtrack.
found = (backtrack(board, word, i+1, j, k+1) or backtrack(board, word, i-1, j, k+1) or backtrack(board, word, i, j+1, k+1) or backtrack(board, word, i, j-1, k+1)) board[i][j] = temp return found
Summary:
Backtracking DFS from each cell. At each step, check bounds and character match. Mark cells as visited during exploration and restore them when backtracking. Try all four directions recursively.
Time and Space Complexity:
Time Complexity: O(m * n * 4^L) - for each cell, we may explore paths of length L with 4 directions.
Space Complexity: O(L) - recursion depth equals the word length.
Python Solution:
def exist(board, word):
def backtrack(i, j, k):
if k == len(word):
return True
if i < 0 or i >= len(board) or j < 0 or j >= len(board[0]) or board[i][j] != word[k]:
return False
temp = board[i][j]
board[i][j] = '#'
found = (backtrack(i+1, j, k+1) or backtrack(i-1, j, k+1) or
backtrack(i, j+1, k+1) or backtrack(i, j-1, k+1))
board[i][j] = temp
return found
for i in range(len(board)):
for j in range(len(board[0])):
if backtrack(i, j, 0):
return True
return FalseJavaScript Solution:
var exist = function(board, word) {
const backtrack = (i, j, k) => {
if (k === word.length) return true;
if (i < 0 || i >= board.length || j < 0 || j >= board[0].length || board[i][j] !== word[k]) return false;
const temp = board[i][j];
board[i][j] = '#';
const found = backtrack(i+1, j, k+1) || backtrack(i-1, j, k+1) ||
backtrack(i, j+1, k+1) || backtrack(i, j-1, k+1);
board[i][j] = temp;
return found;
};
for (let i = 0; i < board.length; i++)
for (let j = 0; j < board[0].length; j++)
if (backtrack(i, j, 0)) return true;
return false;
};Java Solution:
class Solution {
public boolean exist(char[][] board, String word) {
for (int i = 0; i < board.length; i++)
for (int j = 0; j < board[0].length; j++)
if (backtrack(board, word, i, j, 0)) return true;
return false;
}
private boolean backtrack(char[][] board, String word, int i, int j, int k) {
if (k == word.length()) return true;
if (i < 0 || i >= board.length || j < 0 || j >= board[0].length || board[i][j] != word.charAt(k)) return false;
char temp = board[i][j];
board[i][j] = '#';
boolean found = backtrack(board, word, i+1, j, k+1) || backtrack(board, word, i-1, j, k+1) ||
backtrack(board, word, i, j+1, k+1) || backtrack(board, word, i, j-1, k+1);
board[i][j] = temp;
return found;
}
}