Swiftorial Logo
Home
Swift Lessons
Matchups
CodeSnaps
Tutorials
Career
Resources
Word Search in 2D Board

Word Search in 2D Board

Problem Statement

Given a 2D board of characters and a word, determine if the word exists in the grid. The word must be constructed from adjacent cells (horizontally or vertically), without reusing any cell. This medium-level problem uses backtracking to explore all paths in the grid—like a treasure hunt through a maze of letters!

Example

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

Output: true (path: A→B→C→C→E→D)

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

Output: true (path: S→E→E)

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

Output: false (no valid path without reuse)

Code

Java
Python
JavaScript
public 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 (dfs(board, word, i, j, 0)) {
                    return true;
                }
            }
        }
        return false;
    }
    
    private boolean dfs(char[][] board, String word, int i, int j, int index) {
        if (index == word.length()) return true;
        if (i < 0 || i >= board.length || j < 0 || j >= board[0].length || board[i][j] != word.charAt(index)) {
            return false;
        }
        char temp = board[i][j];
        board[i][j] = '#'; // Mark as visited
        boolean found = dfs(board, word, i+1, j, index+1) ||
                        dfs(board, word, i-1, j, index+1) ||
                        dfs(board, word, i, j+1, index+1) ||
                        dfs(board, word, i, j-1, index+1);
        board[i][j] = temp; // Backtrack
        return found;
    }
}
            
def exist(board, word):
    def dfs(i, j, index):
        if index == len(word):
            return True
        if (i < 0 or i >= len(board) or j < 0 or j >= len(board[0]) or 
            board[i][j] != word[index]):
            return False
        temp = board[i][j]
        board[i][j] = "#"  # Mark as visited
        found = (dfs(i+1, j, index+1) or
                 dfs(i-1, j, index+1) or
                 dfs(i, j+1, index+1) or
                 dfs(i, j-1, index+1))
        board[i][j] = temp  # Backtrack
        return found
    
    for i in range(len(board)):
        for j in range(len(board[0])):
            if dfs(i, j, 0):
                return True
    return False

# Example usage
board = [["A","B","C","E"], ["S","F","C","S"], ["A","D","E","E"]]
print(exist(board, "ABCCED"))  # True
print(exist(board, "SEE"))     # True
print(exist(board, "ABCB"))    # False
            
function exist(board, word) {
    function dfs(i, j, index) {
        if (index === word.length) return true;
        if (i < 0 || i >= board.length || j < 0 || j >= board[0].length || 
            board[i][j] !== word[index]) {
            return false;
        }
        let temp = board[i][j];
        board[i][j] = "#"; // Mark as visited
        let found = dfs(i+1, j, index+1) ||
                    dfs(i-1, j, index+1) ||
                    dfs(i, j+1, index+1) ||
                    dfs(i, j-1, index+1);
        board[i][j] = temp; // Backtrack
        return found;
    }
    
    for (let i = 0; i < board.length; i++) {
        for (let j = 0; j < board[0].length; j++) {
            if (dfs(i, j, 0)) return true;
        }
    }
    return false;
}

// Example usage
const board = [["A","B","C","E"], ["S","F","C","S"], ["A","D","E","E"]];
console.log(exist(board, "ABCCED")); // true
console.log(exist(board, "SEE"));    // true
console.log(exist(board, "ABCB"));   // false
            

Explanation

  • Base Case: If index equals word length, the word is found.
  • DFS: Explore all four directions (up, down, left, right) from each cell.
  • Backtracking: Mark cells as visited (e.g., with '#') and restore them after exploration.
  • Flow Example ("SEE"): Start at S(1,0) → E(1,1) → E(2,1), marking and unmarking along the way.
  • Validation: Check boundaries and character matches before proceeding.

Note

Time complexity is O(M * N * 4^L) where M and N are board dimensions, L is word length (4 directions per cell). Space complexity is O(L) for the call stack. It’s a thrilling grid adventure!