Open In App

Word Search - Check if a word exists in a grid or not

Last Updated : 30 Jan, 2025
Summarize
Comments
Improve
Suggest changes
Share
Like Article
Like
Report

Given a 2-D grid of characters mat[][] and a string word, the task is to check if that word exist in the grid mat[][] or not. A word can be matched in 4 directions at any point. The 4 directions are horizontally left and right, vertically up and down

Examples: 

Input: mat[][] = [['T', 'E', 'E'],
['S', 'G', 'K'],
['T', 'E', 'L']]
word = "GEEK"
Output: true
Explanation: Word "GEEK" can be found in the given grid as follows

geek

Input: mat[][] = [['T', 'E', 'U'],
['S', 'G', 'K'],
['T', 'E', 'L']]
word = "GEEK"
Output: false
Explanation: Word "GEEK" cannot be found in the given grid.

geeks


Using Backtracking

The idea is to use backtracking to find a word in a grid by exploring different paths.

  • We traverse through the entire grid, and whenever we find the first letter of the word, we start a recursive search from that cell.
  • From the current matching cell, we check all four possible directions (down, right, up, left) to continue matching the remaining letters of the word.
  • As we explore each direction, we temporarily replace the value with another value the current cell to mark it as visited to avoid using this cell twice within the same path. After exploring a path, we backtrack by placing the original value at the cell, allowing it to be reused in other paths.
  • When all characters of the word were successfully matched, return true.

Note: When we go out of bounds or hit an unmatched character, we backtrack to previous matched cell and try another direction.


C++
// C++ program to check if the word exists in the grid or not

#include <iostream>
#include <vector>
using namespace std;

// Function to check if a word exists in a grid
// starting from the first match in the grid
// wIdx: index till which pattern is matched
// x, y: current position in 2D array
bool findMatch(vector<vector<char>> &mat, string word, int x, int y, int wIdx) {
    int wLen = word.length();
	int n = mat.size();
  	int m = mat[0].size();
  
    // Pattern matched
    if (wIdx == wLen)
        return true;

    // Out of Boundary
    if (x < 0 || y < 0 || x >= n || y >= m)
        return false;

    // If grid matches with a letter while
    // recursion
    if (mat[x][y] == word[wIdx]) {

        // Marking this cell as visited
        char temp = mat[x][y];
        mat[x][y] = '#';

        // finding subpattern in 4 directions
        bool res = findMatch(mat, word, x - 1, y, wIdx + 1) ||
                   findMatch(mat, word, x + 1, y, wIdx + 1) ||
                   findMatch(mat, word, x, y - 1, wIdx + 1) ||
                   findMatch(mat, word, x, y + 1, wIdx + 1);

        // marking this cell as unvisited again
        mat[x][y] = temp;
        return res;
    }
  	
  	// Not matching then return false
    return false;
}

// Function to check if the word exists in the matrix or not
bool isWordExist(vector<vector<char>> &mat, string word) {
    int wLen = word.length();
	int n = mat.size();
  	int m = mat[0].size();
  
    // if total characters in matrix is
    // less than word length
    if (wLen > n * m)
        return false;

    // Traverse in the grid
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {

            // If first letter matches, then recur and check
            if (mat[i][j] == word[0]){
                if (findMatch(mat, word, i, j, 0))
                    return true;
            }
        }
    }
    return false;
}

int main() {
    vector<vector<char>> mat = { {'a', 'x', 'm', 'y'}, 
                                  {'b', 'g', 'd', 'f'}, 
                                  {'x', 'e', 'e', 't'}, 
                                  {'r', 'a', 'k', 's'} };
  	string word = "geeks";	
    cout << (isWordExist(mat, word) ? "true" : "false");

    return 0;
}
Java
// Java program to check if the word exists in the grid or not

import java.util.*;

class GfG {
  
    // Function to check if a word exists in a grid
    // starting from the first match in the grid
    // wIdx: index till which pattern is matched
	// x, y: current position in 2D array
    static boolean findMatch(char[][] mat, String word, int x, int y, 
                             							  int wIdx) {
        int wLen = word.length();
        int n = mat.length;
        int m = mat[0].length;

        // Pattern matched
        if (wIdx == wLen)
            return true;

        // Out of Boundary
        if (x < 0 || y < 0 || x >= n || y >= m)
            return false;

        // If grid matches with a letter while recursion
        if (mat[x][y] == word.charAt(wIdx)) {
            // Marking this cell as visited
            char temp = mat[x][y];
            mat[x][y] = '#';

            // finding subpattern in 4 directions
            boolean res = findMatch(mat, word, x - 1, y, wIdx + 1) ||
                          findMatch(mat, word, x + 1, y, wIdx + 1) ||
                          findMatch(mat, word, x, y - 1, wIdx + 1) ||
                          findMatch(mat, word, x, y + 1, wIdx + 1);

            // marking this cell as unvisited again
            mat[x][y] = temp;
            return res;
        }

        // Not matching then return false
        return false;
    }

    // Function to check if the word exists in the matrix or not
    static boolean isWordExist(char[][] mat, String word) {
        int wLen = word.length();
        int n = mat.length;
        int m = mat[0].length;

        // if total characters in matrix is less than word length
        if (wLen > n * m)
            return false;

        // Traverse in the grid
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                
                // If first letter matches, then recur and check
                if (mat[i][j] == word.charAt(0)) {
                    if (findMatch(mat, word, i, j, 0))
                        return true;
                }
            }
        }
        return false;
    }

    public static void main(String[] args) {
        char[][] mat = {{'a', 'x', 'm', 'y'},
                         {'b', 'g', 'd', 'f'},
                         {'x', 'e', 'e', 't'},
                         {'r', 'a', 'k', 's'}};
        String word = "geeks";
        System.out.println(isWordExist(mat, word));
    }
}
Python
# Python program to check if the word exists in the grid or not

# Function to check if a word exists in a grid
# starting from the first match in the grid
# wIdx: index till which pattern is matched
# x, y: current position in 2D array
def findMatch(mat, word, x, y, wIdx):
    wLen = len(word)
    n = len(mat)
    m = len(mat[0])
  
    # Pattern matched
    if wIdx == wLen:
        return True

    # Out of Boundary
    if x < 0 or y < 0 or x >= n or y >= m:
        return False

    # If grid matches with a letter while
    # recursion
    if mat[x][y] == word[wIdx]:

        # Marking this cell as visited
        temp = mat[x][y]
        mat[x][y] = '#'

        # finding subpattern in 4 directions
        res = (findMatch(mat, word, x - 1, y, wIdx + 1) or
               findMatch(mat, word, x + 1, y, wIdx + 1) or
               findMatch(mat, word, x, y - 1, wIdx + 1) or
               findMatch(mat, word, x, y + 1, wIdx + 1))

        # marking this cell as unvisited again
        mat[x][y] = temp
        return res
  
    # Not matching then return false
    return False

def isWordExist(mat, word):
    wLen = len(word)
    n = len(mat)
    m = len(mat[0])
  
    # if total characters in matrix is
    # less than word length
    if wLen > n * m:
        return False

    # Traverse in the grid
    for i in range(n):
        for j in range(m):

            # If first letter matches, then recur and check
            if mat[i][j] == word[0]:
                if findMatch(mat, word, i, j, 0):
                    return True
    return False

if __name__ == "__main__":
    mat = [['a', 'x', 'm', 'y'], 
           ['b', 'g', 'd', 'f'], 
           ['x', 'e', 'e', 't'], 
           ['r', 'a', 'k', 's']]
    word = "geeks"  
    print("true" if isWordExist(mat, word) else "false")
C#
// C# program to check if the word exists in the grid or not

using System;

class GfG {
  
    // Function to check if a word exists in a grid
    // starting from the first match in the grid
    // wIdx: index till which pattern is matched
    // x, y: current position in 2D array
    static bool findMatch(char[,] mat, string word, int x, int y, int wIdx) {
        int wLen = word.Length;
        int n = mat.GetLength(0);
        int m = mat.GetLength(1);

        // Pattern matched
        if (wIdx == wLen)
            return true;

        // Out of Boundary
        if (x < 0 || y < 0 || x >= n || y >= m)
            return false;

        // If grid matches with a letter while
        // recursion
        if (mat[x, y] == word[wIdx]) {
            
            // Marking this cell as visited
            char temp = mat[x, y];
            mat[x, y] = '#';

            // finding subpattern in 4 directions
            bool res = findMatch(mat, word, x - 1, y, wIdx + 1) ||
                       findMatch(mat, word, x + 1, y, wIdx + 1) ||
                       findMatch(mat, word, x, y - 1, wIdx + 1) ||
                       findMatch(mat, word, x, y + 1, wIdx + 1);

            // marking this cell as unvisited again
            mat[x, y] = temp;
            return res;
        }

        // Not matching then return false
        return false;
    }

    // Function to check if the word exists in the matrix or not
    static bool isWordExist(char[,] mat, string word) {
        int wLen = word.Length;
        int n = mat.GetLength(0);
        int m = mat.GetLength(1);

        // if total characters in matrix is
        // less than word length
        if (wLen > n * m)
            return false;

        // Traverse in the grid
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
              
                // If first letter matches, then recur and check
                if (mat[i, j] == word[0]) {
                    if (findMatch(mat, word, i, j, 0))
                        return true;
                }
            }
        }
        return false;
    }

    static void Main() {
        char[,] mat = {
            { 'a', 'x', 'm', 'y' },
            { 'b', 'g', 'd', 'f' },
            { 'x', 'e', 'e', 't' },
            { 'r', 'a', 'k', 's' }
        };
        string word = "geeks";
        Console.WriteLine(isWordExist(mat, word) ? "true" : "false");
    }
}
JavaScript
// JavaScript program to check if the word exists in the grid or not

// Function to check if a word exists in a grid
// starting from the first match in the grid
// wIdx: index till which pattern is matched
// x, y: current position in 2D array
function findMatch(mat, word, x, y, wIdx) {
    const wLen = word.length;
    const n = mat.length;
    const m = mat[0].length;

    // Pattern matched
    if (wIdx === wLen)
        return true;

    // Out of Boundary
    if (x < 0 || y < 0 || x >= n || y >= m)
        return false;

    // If grid matches with a letter while
    // recursion
    if (mat[x][y] === word[wIdx]) {
        // Marking this cell as visited
        const temp = mat[x][y];
        mat[x][y] = '#';

        // finding subpattern in 4 directions
        const res = findMatch(mat, word, x - 1, y, wIdx + 1) ||
                    findMatch(mat, word, x + 1, y, wIdx + 1) ||
                    findMatch(mat, word, x, y - 1, wIdx + 1) ||
                    findMatch(mat, word, x, y + 1, wIdx + 1);

        // marking this cell as unvisited again
        mat[x][y] = temp;
        return res;
    }

    // Not matching then return false
    return false;
}

// Function to check if the word exists in the matrix or not
function isWordExist(mat, word) {
    const wLen = word.length;
    const n = mat.length;
    const m = mat[0].length;

    // if total characters in matrix is
    // less than word length
    if (wLen > n * m)
        return false;

    // Traverse in the grid
    for (let i = 0; i < n; i++) {
        for (let j = 0; j < m; j++) {
            
            // If first letter matches, then recur and check
            if (mat[i][j] === word[0]) {
                if (findMatch(mat, word, i, j, 0))
                    return true;
            }
        }
    }
    return false;
}

const mat = [
    ['a', 'x', 'm', 'y'],
    ['b', 'g', 'd', 'f'],
    ['x', 'e', 'e', 't'],
    ['r', 'a', 'k', 's']
];
const word = "geeks";
console.log(isWordExist(mat, word) ? "true" : "false");

Output
Yes

Time Complexity: O(n * m * 3wLen) , where n and m are number of rows and columns of 2-D character array mat[][], and wLen is length of string word.

  • In the backtracking function, we have four directions to explore. However, as we move forward, our choices decrease to three because we won't go back to the direction we just came from. We can visualize our recursive tree as a 3-ary tree with a height of wLen. Thus, the time complexity of the recursive function is O( 3wLen ).
  • This recursive function can be called n * m times in the worst case, so the total time complexity is O(n * m * 3wLen).

Auxiliary Space: O(wLen), which is the memory stack space used during recursion.



Similar Reads