# 79\. Word Search ```python= """ backtracking step 1: if not match or if out-of-bound, return False step 2: add to seen step 3: take OR among: up, down, left, right step 4: remove from seen PS: early stop time: O(N * 3^L) N = m*n L = len(word) space: recursion stack: O(L) """ class Solution: def exist(self, board: List[List[str]], word: str) -> bool: if len(board) == 0 or len(board[0]) == 0: return False m = len(board) n = len(board[0]) def inside(i, j): return 0 <= i < m and 0 <= j < n def backtrack(target_word, i, j, visited): if len(target_word) == 0: return True if (i, j) in visited: return False if not inside(i, j) or target_word[0] != board[i][j]: return False visited.add((i, j)) # try to check here, guarantee backtrack() receive only inbound/unseen i,j up = backtrack(target_word[1:], i - 1, j, visited) down = backtrack(target_word[1:], i + 1, j, visited) left = backtrack(target_word[1:], i, j - 1, visited) right = backtrack(target_word[1:], i, j + 1, visited) # early stop visited.remove((i, j)) return up or down or left or right # Don't need to know all four results for i, row in enumerate(board): for j, ch in enumerate(row): visited = set() if backtrack(word, i, j, visited): return True return False class Solution: def exist(self, board: List[List[str]], word: str) -> bool: if len(board) == 0 or len(board[0]) == 0: return False m = len(board) n = len(board[0]) len_word = len(word) directions = [(-1, 0), (1, 0), (0, -1), (0, 1)] def inside(i, j): return 0 <= i < m and 0 <= j < n def is_matched(k, i, j, visited): # guaranteed i,j to be inbound if board[i][j] != word[k]: return False if k == len_word - 1: # ch is match and it's the last one return True visited.add((i, j)) for di, dj in directions: newi, newj = i + di, j + dj if inside(newi, newj) and (newi, newj) not in visited: if is_matched(k + 1, newi, newj, visited): return True # early stop visited.remove((i, j)) return False visited = set() for i, row in enumerate(board): for j, ch in enumerate(row): if is_matched(0, i, j, visited): return True return False ```