Question

Formatted question description: https://leetcode.ca/all/79.html

79. Word Search

Given a 2D board and a word, find if the word exists in the grid.

The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once.

For example,
Given board =

[
  ['A','B','C','E'],
  ['S','F','C','S'],
  ['A','D','E','E']
]
word = "ABCCED", -> returns true,
word = "SEE", -> returns true,
word = "ABCB", -> returns false.

@tag-array

Algorithm

This question is a typical application of depth-first traversal DFS. The original two-dimensional array is like a maze. You can walk in four directions. We use each number in the two-dimensional array as a starting point to match a given string. We also need a visited array of the same size as the original array, which is of bool type to record whether the current location has been visited, because the topic requires that a cell can only be visited once.

If the current character of the two-dimensional array board is equal to the character corresponding to the target string word, then the DFS recursive function is called respectively for the four adjacent characters of the upper, lower, left, and right directions. As long as one of them returns true, then the corresponding string can be found. Otherwise it can’t be found

Code

Java

  • 
    public class Word_Search {
    
        public class Solution {
    
            int m;
            int n;
    
            public boolean exist(char[][] board, String word) {
                m = board.length;
                n = board[0].length;
    
                boolean result = false;
    
                for (int i = 0; i < m; i++) {
                    for (int j = 0; j < n; j++) {
                        if (dfs(board, word, i, j, 0)) {
                            return true;
                        }
                    }
                }
    
                return result;
            }
    
            public boolean dfs(char[][] board, String word, int i, int j, int wordPos) {
    
                if (wordPos == word.length()) {
                    return true;
                }
    
                // @note: here, return check can remove the boundary check in each recursion, nice!
                if (i < 0 || j < 0 || i >= m || j >= n || board[i][j] != word.charAt(wordPos)) {
                    return false;
                }
    
                char temp = board[i][j];
    
                board[i][j] = '#';
    
                boolean result = ( dfs(board, word, i - 1, j, wordPos + 1)
                                || dfs(board, word, i + 1, j, wordPos + 1)
                                || dfs(board, word, i, j - 1, wordPos + 1)
                                || dfs(board, word, i, j + 1, wordPos + 1));
    
                // restore from `#`
                board[i][j] = temp;
    
                return result;
            }
        }
    }
    
  • // OJ: https://leetcode.com/problems/word-search/
    // Time: O(MN * 4^K)
    // Space: O(K)
    class Solution {
    public:
        bool exist(vector<vector<char>>& A, string s) {
            int M = A.size(), N = A[0].size(), dirs[4][2] = { {0,1},{0,-1},{1,0},{-1,0} };
            function<bool(int, int, int)> dfs = [&](int x, int y, int i) {
                if (x < 0 || x >= M || y < 0 || y >= N || A[x][y] != s[i]) return false;
                if (i + 1 == s.size()) return true;
                char c = A[x][y];
                A[x][y] = 0;
                for (auto &[dx, dy] : dirs) {
                    if (dfs(x + dx, y + dy, i + 1)) return true;
                }
                A[x][y] = c;
                return false;
            };
            for (int i = 0; i < M; ++i) {
                for (int j = 0; j < N; ++j) {
                    if (dfs(i, j, 0)) return true;
                }
            }
            return false;
        }
    };
    
  • class Solution:
      # @param board, a list of lists of 1 length string
      # @param word, a string
      # @return a boolean
      def exist(self, board, word):
        # write your code here
        if word == "":
          return True
        if len(board) == 0:
          return False
        visited = [[0] * len(board[0]) for i in range(0, len(board))]
        directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
    
        def dfs(i, j, board, visited, word, index):
          if word[index] != board[i][j]:
            return False
          if len(word) - 1 == index:
            return True
          for direction in directions:
            ni, nj = i + direction[0], j + direction[1]
            if ni >= 0 and ni < len(board) and nj >= 0 and nj < len(board[0]):
              if visited[ni][nj] == 0:
                visited[ni][nj] = 1
                if dfs(ni, nj, board, visited, word, index + 1):
                  return True
                visited[ni][nj] = 0
          return False
    
        for i in range(0, len(board)):
          for j in range(0, len(board[0])):
            visited[i][j] = 1
            if dfs(i, j, board, visited, word, 0):
              return True
            visited[i][j] = 0
        return False
    
    

All Problems

All Solutions