Skip to main content

Word Search

KANISHKA GUPTA
EditReport

Description:​

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:

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

Example 2:

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

Example 3:

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

Video Explanation​


Approaches:​

1. Recursive Backtracking (DFS)​

To find if a specific word exists in a grid, we can treat the grid as a graph and perform a Depth-First Search (DFS) starting from any cell that matches the first letter of our target word.

  1. Iterate through the Grid: Loop over every cell (i, j) in the matrix. If the cell's character matches the first character of the word, we initiate our recursive DFS from that cell.
  2. DFS / Backtracking Logic:
    • Base Case 1: If we have matched all characters in the word (i.e., our current index equals the length of the word), we found the word! Return true.
    • Base Case 2: If we go out of bounds of the matrix, or if the current cell's character does not match the character at the current index of our word, return false.
    • Mark as Visited: To ensure we don't use the same cell twice in a single word path, we temporarily modify the current cell (e.g., change it to '#' or *).
    • Explore: Recursively call the DFS function for all four adjacent directions (up, down, left, right), incrementing the index by 1.
    • Backtrack: After returning from the recursive calls, we must restore the cell's original character so it can be potentially used in other valid search paths starting from different cells.
  3. Result: If any of our DFS paths return true, the word exists. If we check all paths from all valid starting cells and find nothing, return false.

Complexity​

  • Time Complexity: O(M×N×3L)O(M \times N \times 3^L) where MM is the number of rows, NN is the number of columns, and LL is the length of the word. We iterate through every cell, and in the worst case, the DFS explores 3 directions (since we cannot visit the cell we just came from) for every character up to length LL.
  • Space Complexity: O(L)O(L) for the recursion stack space. The maximum depth of the DFS recursion tree will be equal to the length of the word LL.

Solutions​

class Solution {
public:
bool dfs(vector<vector<char>>& board, const string& word, int i, int j, int index) {
// Base case: entire word is found
if (index == word.length()) return true;

// Check out of bounds or character mismatch
if (i < 0 || i >= board.size() || j < 0 || j >= board[0].size() || board[i][j] != word[index]) {
return false;
}

// Mark as visited by temporarily altering the cell
char temp = board[i][j];
board[i][j] = '#';

// Explore 4 directions
bool 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);

// Backtrack: restore the original character
board[i][j] = temp;

return found;
}

bool exist(vector<vector<char>>& board, const string& word) {
if (board.empty() || board[0].empty() || word.empty()) return false;
for (int i = 0; i < board.size(); i++) {
for (int j = 0; j < board[0].size(); j++) {
// Start DFS if the first character matches
if (board[i][j] == word[0] && dfs(board, word, i, j, 0)) {
return true;
}
}
}
return false;
}
};
Track Your Progress

Done with this topic? Mark it as complete to track your progress.

đŸ’Ŧ Discuss this page

Have a question or spot something confusing in "Word Search"? Ask below — it's backed by GitHub Discussions, so maintainers get notified like any other GitHub activity.