Open In App

Word Search in a 2D Grid of characters

Last Updated : 30 Sep, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

Given a 2D grid m*n of characters and a word, the task is to find all occurrences of the given word in the grid. A word can be matched in all 8 directions at any point. Word is said to be found in a direction if all characters match in this direction (not in zig-zag form).
The 8 directions are, Horizontally Left, Horizontally Right, Vertically Up, Vertically Down and 4 Diagonal directions.

Note: The returning list should be lexicographically smallest. If the word can be found in multiple directions starting from the same coordinates, the list should contain the coordinates only once. 

Examples: 

Input:
grid = {{G,E,E,K,S,F,O,R,G,E,E,K,S}, {G,E,E,K,S,Q,U,I,Z,G,E,E,K}, {I,D,E,Q,A,P,R,A,C,T,I,C,E}}
word = "GEEKS"
Output: {{0,0}, {0,8}, {1,0}}

ex-3_1

Input:
grid = {{a,b,a,b},{a,b,e,b},{e,b,e,b}}
word = "abe"
Output:
{{0,0},{0,2},{1,0}}

2222

[Naive Approach] Using Recursion - O(m*n*k) Time and O(k) Space

Visit each cell in the grid and check in all eight directions (up, down, left, right, and diagonals) to find the word. And for each cell, we try to move in one direction.

  • We keep checking, if the letter in the cell of grid matches the word as we move in the chosen direction.
  • If we find the whole word, we store the starting point.
  • We do this for every cell in the grid recursively.
C++
// C++ program to search a word in a 2D grid
#include <bits/stdc++.h>
using namespace std;


// This function checks if the given 
// coordinate is valid
bool validCoord(int x, int y, int m, int n) {
    if (x>=0 && x<m && y>=0 && y<n)
        return true;
    return false;
}

// This function searches for the given word
// in a given direction from the coordinate.
bool findWord(int index, string word, vector<vector<char>> &grid,
              int x, int y, int dirX, int dirY) {
    
    // if word has been found
    if (index == word.length()) return true;
    
    // if the current coordinate is 
    // valid and characters match, then
    // check the next index
    if (validCoord(x, y, grid.size(), grid[0].size())
        && word[index] == grid[x][y])
        return findWord(index+1, word, grid, x+dirX, 
                        y+dirY, dirX, dirY);
        
    return false;
}

// This function calls search2D for each coordinate
vector<vector<int>>searchWord(vector<vector<char>>grid, 
                              string word){
	int m = grid.size();
	int n = grid[0].size();
	
	vector<vector<int>>ans;
	
    // x and y are used to set the direction in which
	// word needs to be searched.
	vector<int>x = { -1, -1, -1, 0, 0, 1, 1, 1 };
	vector<int>y = { -1, 0, 1, -1, 1, -1, 0, 1 };
	
	for(int i = 0; i < m; i++){
		for(int j = 0; j < n; j++){
		    
		    // Search in all 8 directions
		    for (int k=0; k<8; k++) {
		        
		        // If word is found, then append the 
		        // coordinates into answer and break.
		        if (findWord(0, word, grid, i, j, x[k], y[k])) {
		            ans.push_back({i,j});
		            break;
		        }
		    }
		}
	}
	
	return ans;
}

void printResult(vector<vector<int>> ans) {
    for (int i=0; i<ans.size(); i++) {
        cout << "{" << ans[i][0] << "," << ans[i][1] << "}" << " ";
    }
    cout<<endl;
}

int main() {
    vector<vector<char>> grid = {{'a','b','a','b'},
                                 {'a','b','e','b'},
                                 {'e','b','e','b'}};
    string word = "abe";
    
    vector<vector<int>> ans = searchWord(grid, word);
    
    printResult(ans);
}
Java
// Java program to search a word in a 2D grid
import java.util.*;

class GfG {

    // This function checks if the given
    // coordinate is valid
    static boolean validCoord(int x, int y, int m, int n) {
        if (x >= 0 && x < m && y >= 0 && y < n)
            return true;
        return false;
    }

    // This function searches for the given word
    // in a given direction from the coordinate.
    static boolean findWord(int index, String word, char[][] grid, 
                            int x, int y, int dirX, int dirY) {

        // if word has been found
        if (index == word.length()) return true;

        // if the current coordinate is
        // valid and characters match, then
        // check the next index
        if (validCoord(x, y, grid.length, grid[0].length) && 
        word.charAt(index) == grid[x][y])
            return findWord(index + 1, word, grid, 
                            x + dirX, y + dirY, dirX, dirY);

        return false;
    }

    // This function calls search2D for each coordinate
    static int[][] searchWord(char[][] grid, String word) {
        int m = grid.length;
        int n = grid[0].length;

        List<int[]> ans = new ArrayList<>();

        // x and y are used to set the direction in which
        // word needs to be searched.
        int[] x = { -1, -1, -1, 0, 0, 1, 1, 1 };
        int[] y = { -1, 0, 1, -1, 1, -1, 0, 1 };

        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {

                // Search in all 8 directions
                for (int k = 0; k < 8; k++) {

                    // If word is found, then append the
                    // coordinates into answer and break.
                    if (findWord(0, word, grid, i, j, x[k], y[k])) {
                        ans.add(new int[] { i, j });
                        break;
                    }
                }
            }
        }

        return ans.toArray(new int[0][]);
    }

    static void printResult(int[][] ans) {
        for (int[] a : ans) {
            System.out.print( "{" + a[0] + "," + a[1] + "}" + " ");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        char[][] grid = { { 'a', 'b', 'a', 'b' },
                { 'a', 'b', 'e', 'b' },
                { 'e', 'b', 'e', 'b' } };
        String word = "abe";

        int[][] ans = searchWord(grid, word);

        printResult(ans);
    }
}
Python
# Python program to search a word in a 2D grid

# This function checks if the given
# coordinate is valid
def isValid(x, y, sizeX, sizeY):
    return 0 <= x < sizeX and 0 <= y < sizeY

def findWordInDirection(grid, n, m, word, index,
                        x, y, dirX, dirY):
    if index == len(word):
        return True

    if isValid(x, y, n, m) and word[index] == grid[x][y]:
        return findWordInDirection(grid, n, m, word, index + 1, 
                                   x + dirX, y + dirY, dirX, dirY)

    return False

def searchWord(grid, word):
    ans = []
    n = len(grid)
    m = len(grid[0])

    # Directions for 8 possible movements
    directions = [(1, 0), (-1, 0), (0, 1), (0, -1),
                  (1, 1), (1, -1), (-1, 1), (-1, -1)]

    for i in range(n):
        for j in range(m):
          
            # Check if the first character matches
            if grid[i][j] == word[0]:  
                for dirX, dirY in directions:
                    if findWordInDirection(grid, n, m, word, 0, 
                                           i, j, dirX, dirY):
                        ans.append([i, j])
                        break

    return ans

def printResult(ans):
    for a in ans:
       print(f"{{{a[0]},{a[1]}}}", end=" ")
    print()

if __name__ == "__main__":
    grid = [['a', 'b', 'a', 'b'],
            ['a', 'b', 'e', 'b'],
            ['e', 'b', 'e', 'b']]
    word = "abe"

    ans = searchWord(grid, word)
    printResult(ans)
C#
// C# program to search a word in a 2D grid
using System;
using System.Collections.Generic;

class GfG {

    // This function checks if the given
    // coordinate is valid
    static bool validCoord(int x, int y, int m, int n) {
        if (x >= 0 && x < m && y >= 0 && y < n)
            return true;
        return false;
    }

    // This function searches for the given word
    // in a given direction from the coordinate.
    static bool findWord(int index, string word, char[,] grid, 
                         int x, int y, int dirX, int dirY) {

        // if word has been found
        if (index == word.Length) return true;

        // if the current coordinate is
        // valid and characters match, then
        // check the next index
        if (validCoord(x, y, grid.GetLength(0), grid.GetLength(1)) 
            && word[index] == grid[x, y])
            return findWord(index + 1, word, grid, 
                            x + dirX, y + dirY, dirX, dirY);

        return false;
    }

    // This function calls search2D for each coordinate
    static int[][] searchWord(char[,] grid, string word) {
        int m = grid.GetLength(0);
        int n = grid.GetLength(1);

        List<int[]> ans = new List<int[]>();

        // x and y are used to set the direction in which
        // word needs to be searched.
        int[] x = { -1, -1, -1, 0, 0, 1, 1, 1 };
        int[] y = { -1, 0, 1, -1, 1, -1, 0, 1 };

        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {

                // Search in all 8 directions
                for (int k = 0; k < 8; k++) {

                    // If word is found, then append the
                    // coordinates into answer and break.
                    if (findWord(0, word, grid, i, j, x[k], y[k])) {
                        ans.Add(new int[] { i, j });
                        break;
                    }
                }
            }
        }

        return ans.ToArray();
    }

    static void printResult(int[][] ans) {
        foreach (var a in ans) {
            Console.Write( "{" + a[0] + "," + a[1] + "}" + " ");
        }
        Console.WriteLine();
    }

    static void Main() {
        char[,] grid = {
            { 'a', 'b', 'a', 'b' },
            { 'a', 'b', 'e', 'b' },
            { 'e', 'b', 'e', 'b' }
        };
        string word = "abe";

        int[][] ans = searchWord(grid, word);

        printResult(ans);
    }
}
JavaScript
// JavaScript program to search a word in a 2D grid

// This function checks if the given 
// coordinate is valid
function validCoord(x, y, m, n) {
    return (x >= 0 && x < m && y >= 0 && y < n);
}

// This function searches for the given word
// in a given direction from the coordinate.
function findWord(index, word, grid, x, y, dirX, dirY) {

    // if word has been found
    if (index === word.length) return true;

    // if the current coordinate is 
    // valid and characters match, then
    // check the next index
    if (validCoord(x, y, grid.length, grid[0].length) 
    && word[index] === grid[x][y])
        return findWord(index + 1, word, grid, x + dirX, y + dirY, dirX, dirY);

    return false;
}

// This function calls search2D for each coordinate
function searchWord(grid, word) {
    let m = grid.length;
    let n = grid[0].length;

    let ans = [];

    // x and y are used to set the direction in which
    // word needs to be searched.
    let x = [-1, -1, -1, 0, 0, 1, 1, 1];
    let y = [-1, 0, 1, -1, 1, -1, 0, 1];

    for (let i = 0; i < m; i++) {
        for (let j = 0; j < n; j++) {

            // Search in all 8 directions
            for (let k = 0; k < 8; k++) {

                // If word is found, then append the 
                // coordinates into answer and break.
                if (findWord(0, word, grid, i, j, x[k], y[k])) {
                    ans.push([i, j]);
                    break;
                }
            }
        }
    }

    return ans;
}

function printResult(ans) {
    for (let i = 0; i < ans.length; i++) {
        console.log("{" + ans[i][0] + "," + ans[i][1] + "}");
    }
}

const grid = [
    ['a', 'b', 'a', 'b'],
    ['a', 'b', 'e', 'b'],
    ['e', 'b', 'e', 'b']
];
const word = "abe";

const ans = searchWord(grid, word);

printResult(ans);

Output
{0,0} {0,2} {1,0} 

Time Complexity: O(m*n*k), where m is the number of rows, n is the number of columns and k is the length of word.
Auxiliary Space: O(k), recursion stack space.

[Expected Approach] Using Iteration - O(m*n*k) Time and O(1) Space

This is iterative approach for the above discussed recursive approach. Here, for each cell, we try to move in one direction iteratively.

  • We keep checking, if the letter in the cell of grid matches the word as we move in the chosen direction.
  • If we find the whole word, we store the starting point.
  • We do this for every cell in the grid.
C++
// C++ program to search a word in a 2D grid
#include <bits/stdc++.h>
using namespace std;

// This function searches for the given word
// in all 8 directions from the coordinate.
bool search2D(vector<vector<char>> grid, int row, int col, string word) {
	int m = grid.size();
	int n = grid[0].size();
	
    // return false if the given coordinate
    // does not match with first index char.
    if (grid[row][col] != word[0])
      return false;
 
    int len = word.size();
    
    // x and y are used to set the direction in which
	// word needs to be searched.
	vector<int>x = { -1, -1, -1, 0, 0, 1, 1, 1 };
	vector<int>y = { -1, 0, 1, -1, 1, -1, 0, 1 };
 
    // This loop will search in all the 8 directions
    // one by one. It will return true if one of the 
    // directions contain the word.
    for (int dir = 0; dir < 8; dir++) {
      
        // Initialize starting point for current direction
        int k, currX = row + x[dir], currY = col + y[dir];
 
        // First character is already checked, match remaining
        // characters
        for (k = 1; k < len; k++) {
          
            // break if out of bounds
            if (currX >= m || currX < 0 || currY >= n || currY < 0)
                break;
 
            if (grid[currX][currY] != word[k])
                break;
 
            //  Moving in particular direction
            currX += x[dir], currY += y[dir];
        }
 
        // If all character matched, then value of must
        // be equal to length of word
        if (k == len)
            return true;
    }
    
    // if word is not found in any direction,
    // then return false
    return false;
}

// This function calls search2D for each coordinate
vector<vector<int>>searchWord(vector<vector<char>>grid, string word){
	int m = grid.size();
	int n = grid[0].size();
	
	vector<vector<int>>ans;
	
	for(int i = 0; i < m; i++){
		for(int j = 0; j < n; j++){
		    
		    // if the word is found from this coordinate,
		    // then append it to result.
			if(search2D(grid, i, j, word)){
				ans.push_back({i, j});
			}
		}
	}
	
	return ans;
}

void printResult(vector<vector<int>> ans) {
    for (int i=0; i<ans.size(); i++) {
        cout << "{" << ans[i][0] << "," << ans[i][1] << "}" << " ";
    }
    cout<<endl;
}

int main() {
    vector<vector<char>> grid = 
    {{'a','b','a','b'},{'a','b','e','b'},{'e','b','e','b'}};
    string word = "abe";
    
    vector<vector<int>> ans = searchWord(grid, word);
    
    printResult(ans);
}
Java
// Java program to search word in 2D
// grid in 8 directions
import java.util.*;

class GfG {

    // This function searches for the given word
    // in all 8 directions from the coordinate.
    static boolean search2D(char[][] grid, int row, int col,String word) {
        int m = grid.length;
        int n = grid[0].length;

        // return false if the given coordinate
        // does not match with first index char.
        if (grid[row][col] != word.charAt(0))
            return false;

        int len = word.length();

        // x and y are used to set the direction in which
        // word needs to be searched.
        int[] x = { -1, -1, -1, 0, 0, 1, 1, 1 };
        int[] y = { -1, 0, 1, -1, 1, -1, 0, 1 };

        // This loop will search in all the 8 directions
        for (int dir = 0; dir < 8; dir++) {
            int k, currX = row + x[dir],
                   currY = col + y[dir];

            // First character is already checked, match
            // remaining
            for (k = 1; k < len; k++) {
                if (currX >= m || currX < 0 || currY >= n
                    || currY < 0)
                    break;

                if (grid[currX][currY] != word.charAt(k))
                    break;

                currX += x[dir];
                currY += y[dir];
            }

            if (k == len)
                return true;
        }

        return false;
    }

    // This function calls search2D for each coordinate
    static int[][] searchWord(char[][] grid, String word) {
        int m = grid.length;
        int n = grid[0].length;

        // Max possible occurrences
        int[][] ans = new int[m * n][2];
        int count = 0;

        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (search2D(grid, i, j, word)) {
                    ans[count][0] = i;
                    ans[count][1] = j;
                    count++;
                }
            }
        }

        // Resize the array to fit the actual number of
        // found coordinates
        int[][] result = new int[count][2];
        for (int i = 0; i < count; i++) {
            result[i] = ans[i];
        }

        return result;
    }

    static void printResult(int[][] ans) {
        for (int[] coords : ans) {
            System.out.print( "{" + coords[0] + "," + coords[1] + "}" + " ");
        }
        System.out.println();
    }

    public static void main(String[] args) {
      
        char[][] grid = { { 'a', 'b', 'a', 'b' },
                          { 'a', 'b', 'e', 'b' },
                          { 'e', 'b', 'e', 'b' } };
        String word = "abe";

        int[][] ans = searchWord(grid, word);

        printResult(ans);
    }
}
Python
# Python program to search word in 2D grid in 8 directions

# This function searches for the given word
# in all 8 directions from the coordinate.
def search2D(grid, row, col, word):
    m = len(grid)
    n = len(grid[0])

    # return false if the given coordinate
    # does not match with first index char.
    if grid[row][col] != word[0]:
        return False

    lenWord = len(word)

    # x and y are used to set the direction in which
    # word needs to be searched.
    x = [-1, -1, -1, 0, 0, 1, 1, 1]
    y = [-1, 0, 1, -1, 1, -1, 0, 1]

    # This loop will search in all the 8 directions
    # one by one. It will return true if one of the
    # directions contain the word.
    for dir in range(8):

        # Initialize starting point for current direction
        currX, currY = row + x[dir], col + y[dir]
        k = 1

        while k < lenWord:

            # break if out of bounds
            if currX >= m or currX < 0 or currY >= n or currY < 0:
                break

            # break if characters dont match
            if grid[currX][currY] != word[k]:
                break

            # Moving in particular direction
            currX += x[dir]
            currY += y[dir]
            k += 1

        # If all character matched, then value of must
        # be equal to length of word
        if k == lenWord:
            return True

    # if word is not found in any direction,
    # then return false
    return False

# This function calls search2D for each coordinate


def searchWord(grid, word):
    m = len(grid)
    n = len(grid[0])

    ans = []

    for i in range(m):
        for j in range(n):

            # if the word is found from this coordinate,
                    # then append it to result.
            if search2D(grid, i, j, word):
                ans.append((i, j))

    return ans


def printResult(ans):
    for coord in ans:
        print(f"{{{coord[0]},{coord[1]}}}", end=" ")
    print()


if __name__ == "__main__":
    grid = [['a', 'b', 'a', 'b'],
            ['a', 'b', 'e', 'b'],
            ['e', 'b', 'e', 'b']]
    word = "abe"

    ans = searchWord(grid, word)

    printResult(ans)
C#
// C# program to search word in 2D grid in 8 directions
using System;
using System.Collections.Generic;

class GfG {
    
    // This function searches for the given word
    // in all 8 directions from the coordinate.
    static bool search2D(char[][] grid, int row, int col, string word) {
        int m = grid.Length;
        int n = grid[0].Length;
        
        // return false if the given coordinate
        // does not match with first index char.
        if (grid[row][col] != word[0])
            return false;
        
        int len = word.Length;
        
        // x and y are used to set the direction in which
	    // word needs to be searched.
        int[] x = { -1, -1, -1, 0, 0, 1, 1, 1 };
        int[] y = { -1, 0, 1, -1, 1, -1, 0, 1 };
        
        // This loop will search in all the 8 directions
        // one by one. It will return true if one of the 
        // directions contain the word.
        for (int dir = 0; dir < 8; dir++) {
            
            // Initialize starting point for current direction
            int k, currX = row + x[dir], currY = col + y[dir];
            
            // First character is already checked, match remaining
            // characters
            for (k = 1; k < len; k++) {
                
                // break if out of bounds
                if (currX >= m || currX < 0 || currY >= n || currY < 0)
                    break;
                
                // break if characters dont match
                if (grid[currX][currY] != word[k])
                    break;
                
                // Moving in particular direction
                currX += x[dir];
                currY += y[dir];
            }
            
            // If all character matched, then value of must
            // be equal to length of word
            if (k == len)
                return true;
        }
        
        // if word is not found in any direction,
        // then return false
        return false;
    }
    
    // This function calls search2D for each coordinate
    static List<int[]> searchWord(char[][] grid, string word) {
        int m = grid.Length;
        int n = grid[0].Length;
        List<int[]> ans = new List<int[]>();
        
        // if the word is found from this coordinate,
	    // then append it to result.
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (search2D(grid, i, j, word)) {
                    ans.Add(new int[] { i, j });
                }
            }
        }
        
        return ans;
    }

    static void printResult(List<int[]> ans) {
        foreach (var coord in ans) {
            Console.Write( "{" + coord[0] + "," + coord[1] + "}" + " ");
        }
        Console.WriteLine();
    }

    static void Main() {
        char[][] grid = new char[][] {
            new char[] { 'a', 'b', 'a', 'b' },
            new char[] { 'a', 'b', 'e', 'b' },
            new char[] { 'e', 'b', 'e', 'b' }
        };
        string word = "abe";
        
        List<int[]> ans = searchWord(grid, word);
        
        printResult(ans);
    }
}
JavaScript
// JavaScript program to search word in 2D grid in 8 directions

// This function searches for the given word
// in all 8 directions from the coordinate.
function search2D(grid, row, col, word) {
    let m = grid.length;
    let n = grid[0].length;
    
    // return false if the given coordinate
    // does not match with first index char.
    if (grid[row][col] !== word[0]) return false;
    
    let len = word.length;
    
    // x and y are used to set the direction in which
	// word needs to be searched.
    let x = [-1, -1, -1, 0, 0, 1, 1, 1];
    let y = [-1, 0, 1, -1, 1, -1, 0, 1];
    
    // This loop will search in all the 8 directions
    // one by one. It will return true if one of the 
    // directions contain the word.
    for (let dir = 0; dir < 8; dir++) {
        
        // Initialize starting point for current direction
        let currX = row + x[dir], currY = col + y[dir], k = 1;
        
        // First character is already checked, match remaining
        // characters
        for (k = 1; k < len; k++) {
            
            // break if out of bounds
            if (currX >= m || currX < 0 || currY >= n || currY < 0) break;
            
            // break if characters dont match
            if (grid[currX][currY] !== word[k]) break;
            
            //  Moving in particular direction
            currX += x[dir];
            currY += y[dir];
        }
        
        // If all character matched, then value of must
        // be equal to length of word
        if (k === len) return true;
    }
    
    // if word is not found in any direction,
    // then return false
    return false;
}

// This function calls search2D for each coordinate
function searchWord(grid, word) {
    let m = grid.length;
    let n = grid[0].length;
    let ans = [];
    
    for (let i = 0; i < m; i++) {
        for (let j = 0; j < n; j++) {
            
            // if the word is found from this coordinate,
		    // then append it to result.
            if (search2D(grid, i, j, word)) {
                ans.push([i, j]);
            }
        }
    }
    
    return ans;
}

function printResult(ans) {
    ans.forEach(coord => {
        console.log("{" + coord[0] + "," + coord[1] + "}");;
    });
}

let grid = [
    ['a', 'b', 'a', 'b'],
    ['a', 'b', 'e', 'b'],
    ['e', 'b', 'e', 'b']
];
let word = "abe";

let ans = searchWord(grid, word);
printResult(ans);

Output
{0,0} {0,2} {1,0} 

Time complexity: O(m*n*k), where m is the number of rows, n is the number of columns and k is the length of word.
Auxiliary Space: O(1). 


Next Article

Similar Reads