Post

Backtracking - Word Search

All diagrams presented herein are original creations, meticulously designed to enhance comprehension and recall. Crafting these aids required considerable effort, and I kindly request attribution if this content is reused elsewhere.

Difficulty : Easy

DFS, Backtracking

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.

Example 1:

queens

1
2
Input: board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"
Output: true

Example 2:

queens

1
2
Input: board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "SEE"
Output: true

Example 3:

queens

1
2
Input: board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCB"
Output: false

Solution

Classic backtracking algorithm where we need to run dfs() from every cell of the board. Start by defining the variables.

1
2
ROWS, COLS = len(board), len(board[0])
path_visited = set()

The dfs() will take the row , col and current index in the word is searching for. As stated, need to invoke dfs() from every cell. If any one of the dfs() returns True then return True, otherwise return False.

1
2
3
4
5
for row in range(ROWS):
  for col in range(COLS):
    if dfs(row, col, 0):
      return True
return False

Now define the dfs() function. If the index reaches the end of the word we have found the word. This is our base/terminating condition, so return True

1
2
3
def dfs(row, col, char_index):
  if char_index == len(word):
    return True

Otherwise, make sure the cell is,

  • not outside of the boundary conditions and
  • not visited and
  • The char at current index matches with current char in the cell.

Otherwise return False since this indicates its not end of the word yet and there is no possible solution in this path to explore.

1
2
  if row < 0 or col < 0 or row == ROWS or col == COLS or (row,col) in path_visited or word[char_index]!=board[row][col]:
    return False

Add the location to path_visited .

1
	path_visited.add((row, col))

Now run the dfs() for all the four directions. We need to return the True if any of the dfs() returns True

1
found = dfs(row+1,col,char_index+1) or dfs(row-1,col,char_index+1) or dfs(row,col+1,char_index+1) or dfs(row,col-1,char_index+1)

Now perform the backtracking and return found

1
2
path_visited.remove((row, col))
return found

If no solution found, return False.

Visualize the code below.

word_search

Final Code

Here is the full code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
def word_search(board, word):
    ROWS, COLS = len(board), len(board[0])
    path_visited = set()

    def dfs(row, col, char_index):
        if char_index == len(word):
            return True

        if row < 0 or col < 0 or row == ROWS or col == COLS or (row, col) in path_visited or word[char_index] != board[row][col]:
            return False

        path_visited.add((row, col))

        found = dfs(row+1, col, char_index+1) or dfs(row-1, col, char_index +
                                                     1) or dfs(row, col+1, char_index+1) or dfs(row, col-1, char_index+1)

        path_visited.remove((row, col))
        return found

    for row in range(ROWS):
        for col in range(COLS):
            if dfs(row, col, 0):
                return True

    return False
This post is licensed under CC BY 4.0 by the author.