Word Search in a 2D Grid of characters
Last Updated :
30 Sep, 2024
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}}
Input:
grid = {{a,b,a,b},{a,b,e,b},{e,b,e,b}}
word = "abe"
Output:
{{0,0},{0,2},{1,0}}
[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);
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);
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).
Explore
DSA Fundamentals
Data Structures
Algorithms
Advanced
Interview Preparation
Practice Problem