Check if a word exists in a grid or not
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++
// 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
// 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
# 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 |
C#
// 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 |
Javascript
<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> |
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
C++
#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 // possiblity 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 |
Python3
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 # possiblity 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. |
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.
Please Login to comment...