Given a 2D grid of characters and a word/ multiple words, the task is to check if that word/words exist in the grid 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: grid[][] = {"axmy", "bgdf", "xeet", "raks"}; Output: Yes a x m y b g d f x e e t r a k s Input: grid[][] = {"axmy", "brdf", "xeet", "rass"}; Output : No
Source: Microsoft Interview
Approach when a single word is to be checked : The idea used here is described in the steps below:
- Check every cell, if the cell has the first character, then recur one by one and try all 4 directions from that cell for a match.
- Mark the position in the grid as visited and recur in the 4 possible directions.
- After recurring, again mark the position as unvisited.
- Once all the letters in the word are matched, return true.
Below is the implementation of the above approach:
// C++ program to check if the word // exists in the grid or not #include <bits/stdc++.h> using namespace std;
#define r 4 #define c 5 // Function to check if a word exists in a grid // starting from the first match in the grid // level: index till which pattern is matched // x, y: current position in 2D array bool findmatch( char mat[r], string pat, int x, int y,
int nrow, int ncol, int level)
{ int l = pat.length();
// Pattern matched
if (level == l)
return true ;
// Out of Boundary
if (x < 0 || y < 0 || x >= nrow || y >= ncol)
return false ;
// If grid matches with a letter while
// recursion
if (mat[x][y] == pat[level]) {
// Marking this cell as visited
char temp = mat[x][y];
mat[x][y] = '#' ;
// finding subpattern in 4 directions
bool res = findmatch(mat, pat, x - 1, y, nrow, ncol, level + 1) |
findmatch(mat, pat, x + 1, y, nrow, ncol, level + 1) |
findmatch(mat, pat, x, y - 1, nrow, ncol, level + 1) |
findmatch(mat, pat, x, y + 1, nrow, ncol, level + 1);
// marking this cell
// as unvisited again
mat[x][y] = temp;
return res;
}
else // Not matching then false
return false ;
} // Function to check if the word exists in the grid or not bool checkMatch( char mat[r], string pat, int nrow, int ncol)
{ int l = pat.length();
// if total characters in matrix is
// less than pattern length
if (l > nrow * ncol)
return false ;
// Traverse in the grid
for ( int i = 0; i < nrow; i++) {
for ( int j = 0; j < ncol; j++) {
// If first letter matches, then recur and check
if (mat[i][j] == pat[0])
if (findmatch(mat, pat, i, j, nrow, ncol, 0))
return true ;
}
}
return false ;
} // Driver Code int main()
{ char grid[r] = { "axmy" ,
"bgdf" ,
"xeet" ,
"raks" };
// Function to check if word exists or not
if (checkMatch(grid, "geeks" , r, c))
cout << "Yes" ;
else
cout << "No" ;
return 0;
} |
// Java program to check if the word // exists in the grid or not class GFG
{ static final int r = 4 ;
static final int c = 4 ;
// Function to check if a word exists in a grid // starting from the first match in the grid // level: index till which pattern is matched // x, y: current position in 2D array static boolean findmatch( char mat[][], String pat, int x, int y,
int nrow, int ncol, int level)
{ int l = pat.length();
// Pattern matched
if (level == l)
return true ;
// Out of Boundary
if (x < 0 || y < 0 || x >= nrow || y >= ncol)
return false ;
// If grid matches with a letter while
// recursion
if (mat[x][y] == pat.charAt(level))
{
// Marking this cell as visited
char temp = mat[x][y];
mat[x][y] = '#' ;
// finding subpattern in 4 directions
boolean res = findmatch(mat, pat, x - 1 , y, nrow, ncol, level + 1 ) |
findmatch(mat, pat, x + 1 , y, nrow, ncol, level + 1 ) |
findmatch(mat, pat, x, y - 1 , nrow, ncol, level + 1 ) |
findmatch(mat, pat, x, y + 1 , nrow, ncol, level + 1 );
// marking this cell
// as unvisited again
mat[x][y] = temp;
return res;
}
else // Not matching then false
return false ;
} // Function to check if the word exists in the grid or not static boolean checkMatch( char mat[][], String pat, int nrow, int ncol)
{ int l = pat.length();
// if total characters in matrix is
// less than pattern length
if (l > nrow * ncol)
return false ;
// Traverse in the grid
for ( int i = 0 ; i < nrow; i++)
{
for ( int j = 0 ; j < ncol; j++)
{
// If first letter matches, then recur and check
if (mat[i][j] == pat.charAt( 0 ))
if (findmatch(mat, pat, i, j, nrow, ncol, 0 ))
return true ;
}
}
return false ;
} // Driver Code public static void main(String[] args)
{ char grid[][] = { "axmy" .toCharArray(),
"bgdf" .toCharArray(),
"xeet" .toCharArray(),
"raks" .toCharArray() };
// Function to check if word exists or not
if (checkMatch(grid, "geeks" , r, c))
System.out.print( "Yes" );
else
System.out.print( "No" );
} } // This code is contributed by 29AjayKumar |
# Python3 program to check if the word # exists in the grid or not r = 4
c = 4
# Function to check if a word exists # in a grid starting from the first # match in the grid level: index till # which pattern is matched x, y: current # position in 2D array def findmatch(mat, pat, x, y,
nrow, ncol, level) :
l = len (pat)
# Pattern matched
if (level = = l) :
return True
# Out of Boundary
if (x < 0 or y < 0 or
x > = nrow or y > = ncol) :
return False
# If grid matches with a letter
# while recursion
if (mat[x][y] = = pat[level]) :
# Marking this cell as visited
temp = mat[x][y]
mat[x].replace(mat[x][y], "#" )
# finding subpattern in 4 directions
res = (findmatch(mat, pat, x - 1 , y, nrow, ncol, level + 1 ) |
findmatch(mat, pat, x + 1 , y, nrow, ncol, level + 1 ) |
findmatch(mat, pat, x, y - 1 , nrow, ncol, level + 1 ) |
findmatch(mat, pat, x, y + 1 , nrow, ncol, level + 1 ))
# marking this cell as unvisited again
mat[x].replace(mat[x][y], temp)
return res
else : # Not matching then false
return False
# Function to check if the word # exists in the grid or not def checkMatch(mat, pat, nrow, ncol) :
l = len (pat)
# if total characters in matrix is
# less than pattern length
if (l > nrow * ncol) :
return False
# Traverse in the grid
for i in range (nrow) :
for j in range (ncol) :
# If first letter matches, then
# recur and check
if (mat[i][j] = = pat[ 0 ]) :
if (findmatch(mat, pat, i, j,
nrow, ncol, 0 )) :
return True
return False
# Driver Code if __name__ = = "__main__" :
grid = [ "axmy" , "bgdf" ,
"xeet" , "raks" ]
# Function to check if word
# exists or not
if (checkMatch(grid, "geeks" , r, c)) :
print ( "Yes" )
else :
print ( "No" )
# This code is contributed by Ryuga |
<script> // JavaScript program to check if the word
// exists in the grid or not
let r = 4;
let c = 4;
// Function to check if a word exists in a grid
// starting from the first match in the grid
// level: index till which pattern is matched
// x, y: current position in 2D array
function findmatch(mat, pat, x, y, nrow, ncol, level)
{
let l = pat.length;
// Pattern matched
if (level == l)
return true ;
// Out of Boundary
if (x < 0 || y < 0 || x >= nrow || y >= ncol)
return false ;
// If grid matches with a letter while
// recursion
if (mat[x][y] == pat[level])
{
// Marking this cell as visited
let temp = mat[x][y];
mat[x][y] = '#' ;
// finding subpattern in 4 directions
let res =
findmatch(mat, pat, x - 1, y, nrow, ncol, level + 1) |
findmatch(mat, pat, x + 1, y, nrow, ncol, level + 1) |
findmatch(mat, pat, x, y - 1, nrow, ncol, level + 1) |
findmatch(mat, pat, x, y + 1, nrow, ncol, level + 1);
// marking this cell
// as unvisited again
mat[x][y] = temp;
return res;
}
else // Not matching then false
return false ;
}
// Function to check if the word exists in the grid or not
function checkMatch(mat, pat, nrow, ncol)
{
let l = pat.length;
// if total characters in matrix is
// less than pattern length
if (l > nrow * ncol)
return false ;
// Traverse in the grid
for (let i = 0; i < nrow; i++)
{
for (let j = 0; j < ncol; j++)
{
// If first letter matches, then recur and check
if (mat[i][j] == pat[0])
if (findmatch(mat, pat, i, j, nrow, ncol, 0))
return true ;
}
}
return false ;
}
let grid = [ "axmy" .split( '' ),
"bgdf" .split( '' ),
"xeet" .split( '' ),
"raks" .split( '' ) ];
// Function to check if word exists or not
if (checkMatch(grid, "geeks" , r, c))
document.write( "Yes" );
else
document.write( "No" );
</script> |
// C# program to check if the word // exists in the grid or not using System;
class GFG
{ static readonly int r = 4;
static readonly int c = 4;
// Function to check if a word exists in a grid // starting from the first match in the grid // level: index till which pattern is matched // x, y: current position in 2D array static bool findmatch( char [,]mat, String pat, int x, int y,
int nrow, int ncol, int level)
{ int l = pat.Length;
// Pattern matched
if (level == l)
return true ;
// Out of Boundary
if (x < 0 || y < 0 || x >= nrow || y >= ncol)
return false ;
// If grid matches with a letter while
// recursion
if (mat[x, y] == pat[level])
{
// Marking this cell as visited
char temp = mat[x, y];
mat[x, y] = '#' ;
// finding subpattern in 4 directions
bool res = findmatch(mat, pat, x - 1, y, nrow, ncol, level + 1) |
findmatch(mat, pat, x + 1, y, nrow, ncol, level + 1) |
findmatch(mat, pat, x, y - 1, nrow, ncol, level + 1) |
findmatch(mat, pat, x, y + 1, nrow, ncol, level + 1);
// marking this cell
// as unvisited again
mat[x, y] = temp;
return res;
}
else // Not matching then false
return false ;
} // Function to check if the word exists in the grid or not static bool checkMatch( char [,]mat, String pat, int nrow, int ncol)
{ int l = pat.Length;
// if total characters in matrix is
// less than pattern length
if (l > nrow * ncol)
return false ;
// Traverse in the grid
for ( int i = 0; i < nrow; i++)
{
for ( int j = 0; j < ncol; j++)
{
// If first letter matches, then recur and check
if (mat[i, j] == pat[0])
if (findmatch(mat, pat, i, j, nrow, ncol, 0))
return true ;
}
}
return false ;
} // Driver Code public static void Main(String[] args)
{ char [,]grid = { { 'a' , 'x' , 'm' , 'y' },
{ 'b' , 'g' , 'd' , 'f' },
{ 'x' , 'e' , 'e' , 't' },
{ 'r' , 'a' , 'k' , 's' } };
// Function to check if word exists or not
if (checkMatch(grid, "geeks" , r, c))
Console.Write( "Yes" );
else
Console.Write( "No" );
} } // This code is contributed by 29AjayKumar |
Yes
Time Complexity: O(r*c), as we are using recursion to traverse the matrix. Where r and c are the rows and columns of the grid.
Auxiliary Space: O(r*c), as we are using extra space for the matrix. Where r and c are the rows and columns of the grid.
Approach when a group of words are to be checked : The idea used here is described in the steps below:
- iterate through group of words and check every cell, if the cell has the first character, then recur one by one and try all 4 directions from that cell for a match.
- Mark the position in the grid as visited and recur in the 4 possible directions.
- After recurring, again mark the position as unvisited.
- Once all the letters in the word are matched, return true, put it in answer list.
- return the answer list from a function and display
#include <bits/stdc++.h> using namespace std;
// making a solution class to solve the problem and to keep // the components and functions of solution together class Solution {
public :
// making the possible moves in movers array
// if 4 directions are to be checked
vector<vector< int > > mover
= { { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 } };
// if 8 directions are to be checked
// vector<vector<int>>mover={{1,0},{0,1},{-1,0},{0,-1},{1,1},{-1,-1},{1,-1},{-1,1}};
// making the board global variable
vector<vector< char > > board;
// depth first search for the string, with the
// coordinates and a visited array to take care that we
// do not overlap the places visited already
bool dfs( int x, int y, string& s,
vector<vector< bool > > vis)
{
// if string length becomes 0 means string is found
if (s.length() == 0)
return true ;
vis[x][y] = true ;
// making a solution boolean to see if we can
// perform depth search to find answer
bool sol = false ;
// making possible moves
for ( int i = 0; i < mover.size(); i++) {
int curr_x = mover[i][0] + x;
int curr_y = mover[i][1] + y;
// checking for out of bound areas
if (curr_x >= 0 && curr_x < board.size()) {
if (curr_y >= 0
&& curr_y < board[0].size()) {
// checking for similarity in the first
// letter and the visited array
if (board[curr_x][curr_y] == s[0]
&& vis[curr_x][curr_y] == false ) {
string k = s.substr(
1); // removing the first letter
// from the string
sol |= dfs(curr_x, curr_y, k, vis);
}
}
}
}
return sol;
}
// making a function findwords to find words along with
// their location which inputs the board and list of
// words
vector<string> findWords(vector<vector< char > >& board,
vector<string>& words)
{
this ->board
= board; // making board a global variable
vector<string> ans;
vector<vector< bool > > vis(
board.size(),
vector< bool >(board[0].size(),
false )); // visited array
for ( auto & word : words) {
for ( int i = 0; i < board.size(); i++) {
for ( int j = 0; j < board[i].size(); j++) {
if (board[i][j] == word[0]) {
// if first letter of(i,j)==
// string's first letter then we can
// perform dfs to check the
// possibility of string being present
// from location (i,j)
string s = word.substr(1);
if (dfs(i, j, s, vis)) {
ans.push_back(word);
break ;
}
}
}
if (ans.size() && ans.back() == word)
break ;
}
}
return ans;
}
}; int main()
{ // making 1 instance of class solution as solver
Solution solver;
vector<vector< char > > board
= { { 'o' , 'a' , 'a' , 'n' },
{ 'e' , 't' , 'a' , 'e' },
{ 'i' , 'h' , 'k' , 'r' },
{ 'i' , 'f' , 'l' , 'v' } };
vector<string> words = { "oath" , "pea" , "eat" , "rain" };
// using the function findwords from our solution class
// to find the answer
vector<string> ans = solver.findWords(board, words);
// printing the answer
cout << "words present:\n" ;
for ( auto & part : ans)
cout << part << endl;
return 0;
} //contributed by Naman Anand
|
import java.util.*;
class Solution {
// Making the possible moves in movers array
int [][] mover = {{ 1 , 0 }, { 0 , 1 }, {- 1 , 0 }, { 0 , - 1 }};
// Making the board global variable
char [][] board;
// Depth first search for the string, with the
// coordinates and a visited array to take care that we
// do not overlap the places visited already
public boolean dfs( int x, int y, String s, boolean [][] vis) {
// If string length becomes 0 means string is found
if (s.length() == 0 ) {
return true ;
}
vis[x][y] = true ;
// Making a solution boolean to see if we can
// perform depth search to find answer
boolean sol = false ;
// Making possible moves
for ( int i = 0 ; i < mover.length; i++) {
int curr_x = mover[i][ 0 ] + x;
int curr_y = mover[i][ 1 ] + y;
// Checking for out of bound areas
if (curr_x >= 0 && curr_x < board.length) {
if (curr_y >= 0 && curr_y < board[ 0 ].length) {
// Checking for similarity in the first
// letter and the visited array
if (board[curr_x][curr_y] == s.charAt( 0 ) && !vis[curr_x][curr_y]) {
// Removing the first letter from the string
String k = s.substring( 1 );
sol |= dfs(curr_x, curr_y, k, vis);
}
}
}
}
return sol;
}
// Making a function findWords to find words along with
// their location which inputs the board and list of
// words
public List<String> findWords( char [][] board, String[] words) {
this .board = board;
List<String> ans = new ArrayList<>();
for (String word : words) {
boolean [][] vis = new boolean [board.length][board[ 0 ].length];
for ( int i = 0 ; i < board.length; i++) {
for ( int j = 0 ; j < board[i].length; j++) {
if (board[i][j] == word.charAt( 0 )) {
// If first letter of(i,j)==
// string's first letter then we can
// perform dfs to check the
// possibility of string being present
// from location (i,j)
String s = word.substring( 1 );
if (dfs(i, j, s, vis)) {
ans.add(word);
break ;
}
}
}
if (!ans.isEmpty() && ans.get(ans.size() - 1 ).equals(word)) {
break ;
}
}
}
return ans;
}
} class Main {
public static void main(String[] args) {
// making 1 instance of class solution as solver
Solution solver = new Solution();
char [][] board = { { 'o' , 'a' , 'a' , 'n' }, { 'e' , 't' , 'a' , 'e' }, { 'i' , 'h' , 'k' , 'r' }, { 'i' , 'f' , 'l' , 'v' } };
String[] words = { "oath" , "pea" , "eat" , "rain" };
//Function call
System.out.println( "Words present: " );
List<String> arr = solver.findWords(board, words);
for ( int i = 0 ; i < arr.size(); i++) {
System.out.println(arr.get(i));
}
}
} |
class Solution:
# making the possible moves in movers array
# if 4 directions are to be checked
mover = [ [ 1 , 0 ], [ 0 , 1 ], [ - 1 , 0 ], [ 0 , - 1 ] ]
# if 8 directions are to be checked
# mover = [[1,0], [0,1], [-1,0], [0,-1], [1,1], [-1,-1], [1,-1], [-1,1]]
# making the board global variable
board = []
# depth first search for the string, with the
# coordinates and a visited array to take care that we
# do not overlap the places visited already
def dfs( self , x, y, s, vis):
# if string length becomes 0 means string is found
if len (s) = = 0 :
return True
vis[x][y] = True
# making a solution boolean to see if we can
# perform depth search to find answer
sol = False
# making possible moves
for i in range ( len ( self .mover)):
curr_x = self .mover[i][ 0 ] + x
curr_y = self .mover[i][ 1 ] + y
# checking for out of bound areas
if curr_x > = 0 and curr_x < len ( self .board):
if curr_y > = 0 and curr_y < len ( self .board[ 0 ]):
# checking for similarity in the first
# letter and the visited array
if self .board[curr_x][curr_y] = = s[ 0 ] and vis[curr_x][curr_y] = = False :
# removing the first letter from the string
k = s[ 1 :]
sol | = self .dfs(curr_x, curr_y, k, vis)
return sol
# making a function findwords to find words along with
# their location which inputs the board and list of
# words
def findWords( self , board, words):
self .board = board
ans = []
for word in words:
vis = [[ False for _ in range ( len (board[ 0 ]))] for _ in range ( len (board))]
for i in range ( len (board)):
for j in range ( len (board[i])):
if board[i][j] = = word[ 0 ]:
# if first letter of(i,j)==
# string's first letter then we can
# perform dfs to check the
# possibility of string being present
# from location (i,j)
s = word[ 1 :]
if self .dfs(i, j, s, vis):
ans.append(word)
break
if ans and ans[ - 1 ] = = word:
break
return ans
# making 1 instance of class solution as solver solver = Solution()
board = [ [ 'o' , 'a' , 'a' , 'n' ], [ 'e' , 't' , 'a' , 'e' ], [ 'i' , 'h' , 'k' , 'r' ], [ 'i' , 'f' , 'l' , 'v' ] ]
words = [ "oath" , "pea" , "eat" , "rain" ]
#Function call print ( "Words present: " )
arr = solver.findWords(board, words)
for i in range ( len (arr)):
print (arr[i])
# This code is contributed by lokeshpotta20.
|
class Solution { // making the possible moves in movers array
// if 4 directions are to be checked
mover = [ [1, 0], [0, 1], [-1, 0], [0, -1] ];
// if 8 directions are to be checked
// mover = [[1,0], [0,1], [-1,0], [0,-1], [1,1], [-1,-1], [1,-1], [-1,1]];
// making the board global variable
board = [];
// depth first search for the string, with the
// coordinates and a visited array to take care that we
// do not overlap the places visited already
dfs(x, y, s, vis) {
// if string length becomes 0 means string is found
if (s.length === 0) {
return true ;
}
vis[x][y] = true ;
// making a solution boolean to see if we can
// perform depth search to find answer
let sol = false ;
// making possible moves
for (let i = 0; i < this .mover.length; i++) {
let curr_x = this .mover[i][0] + x;
let curr_y = this .mover[i][1] + y;
// checking for out of bound areas
if (curr_x >= 0 && curr_x < this .board.length) {
if (curr_y >= 0 && curr_y < this .board[0].length) {
// checking for similarity in the first
// letter and the visited array
if ( this .board[curr_x][curr_y] == s[0] && vis[curr_x][curr_y] == false ) {
// removing the first letter from the string
let k = s.substring(1);
sol |= this .dfs(curr_x, curr_y, k, vis);
}
}
}
}
return sol;
}
// making a function findwords to find words along with
// their location which inputs the board and list of
// words
findWords(board, words) {
this .board = board;
let ans = [];
for (let word of words) {
let vis = new Array(board.length).fill( false ).map(() => new Array(board[0].length).fill( false ));
for (let i = 0; i < board.length; i++) {
for (let j = 0; j < board[i].length; j++) {
if (board[i][j] == word[0]) {
// if first letter of(i,j)==
// string's first letter then we can
// perform dfs to check the
// possibility of string being present
// from location (i,j)
let s = word.substring(1);
if ( this .dfs(i, j, s, vis)) {
ans.push(word);
break ;
}
}
}
if (ans.length && ans[ans.length - 1] == word) {
break ;
}
}
}
return ans;
}
} // making 1 instance of class solution as solver let solver = new Solution();
let board = [ ['o ',' a ',' a ',' n '],
[' e ',' t ',' a ',' e '],
[' i ',' h ',' k ',' r '],
[' i ',' f ',' l ',' v']
]; let words = [ "oath" , "pea" , "eat" , "rain" ];
// Call the findWords method to search for words const foundWords = solver.findWords(board, words); // Print the words that were found console.log( "Words present:" );
foundWords.forEach(word => console.log(word)); |
// c# program for the above approach using System;
using System.Collections.Generic;
using System.Linq;
class Solution {
// Making the possible moves in moves array
private static readonly int [][] Moves = {
new [] {1, 0}, new [] {0, 1}, new [] {-1, 0}, new [] {0, -1}
};
// Making the board global variable
private char [][] _board;
// Making a function findWords to find words along with
// their location which inputs the board and list of
// words
public IList< string > FindWords( char [][] board, string [] words) {
_board = board;
var result = new List< string >();
foreach ( var word in words) {
if (Exists(word)) {
result.Add(word);
}
}
return result;
}
private bool Exists( string word) {
for ( var i = 0; i < _board.Length; i++) {
for ( var j = 0; j < _board[0].Length; j++) {
if (_board[i][j] == word[0] && Search(word, i, j, 0)) {
return true ;
}
}
}
return false ;
}
private bool Search( string word, int i, int j, int k) {
if (k == word.Length) {
return true ;
}
if (i < 0 || j < 0 || i == _board.Length || j == _board[0].Length) {
return false ;
}
if (_board[i][j] != word[k]) {
return false ;
}
var temp = _board[i][j];
_board[i][j] = '#' ;
foreach ( var move in Moves) {
if (Search(word, i + move[0], j + move[1], k + 1)) {
_board[i][j] = temp;
return true ;
}
}
_board[i][j] = temp;
return false ;
}
} // Driver Code public class Program {
public static void Main() {
// making 1 instance of class solution as solver
var solver = new Solution();
var board = new char [][] {
new char [] { 'o' , 'a' , 'a' , 'n' },
new char [] { 'e' , 't' , 'a' , 'e' },
new char [] { 'i' , 'h' , 'k' , 'r' },
new char [] { 'i' , 'f' , 'l' , 'v' }
};
var words = new string [] { "oath" , "pea" , "eat" , "rain" };
var ans = solver.FindWords(board, words);
Console.WriteLine( "Words present:" );
foreach ( var word in ans) {
Console.WriteLine(word);
}
}
} // This code is contributed by Prince Kumar |
words present: oath eat
Time Complexity: O(r*c*len(words)*number of words), as we are using recursion to traverse the matrix. Where r and c are the rows and columns of the grid.
Auxiliary Space: O(r*c*number of words), as we are using extra space for the matrix. Where r and c are the rows and columns of the grid.