Given a 2D grid m*n of characters and a word, 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] Recursion - O(m × n × WordLength) Time and O(L) Space
We check every cell of the grid as a starting point and try to match the word in all 8 directions. If characters match continuously in any one direction, we confirm the word exists from that position.
Define 8 possible directions using two arrays
Traverse through all cells and for each cell (i, j) check if it matches first character, try all 8 directions from that cell using recursion.
At each step check bounds and character match
If found in any direction, return true from the recursive function and store (i, j) in the caller.
C++
#include<iostream>usingnamespacestd;boolvalidCoord(intx,inty,intm,intn){if(x>=0&&x<m&&y>=0&&y<n)returntrue;returnfalse;}boolfindWord(intindex,stringword,vector<vector<char>>&grid,intx,inty,intdirX,intdirY){// if word has been foundif(index==word.length())returntrue;// if the current coordinate is // valid and characters match, then// check the next indexif(validCoord(x,y,grid.size(),grid[0].size())&&word[index]==grid[x][y])returnfindWord(index+1,word,grid,x+dirX,y+dirY,dirX,dirY);returnfalse;}vector<vector<int>>searchWord(vector<vector<char>>grid,stringword){intm=grid.size();intn=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(inti=0;i<m;i++){for(intj=0;j<n;j++){// Search in all 8 directionsfor(intk=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;}}}}returnans;}voidprintResult(vector<vector<int>>ans){for(inti=0;i<ans.size();i++){cout<<"{"<<ans[i][0]<<","<<ans[i][1]<<"}"<<" ";}cout<<endl;}intmain(){vector<vector<char>>grid={{'a','b','a','b'},{'a','b','e','b'},{'e','b','e','b'}};stringword="abe";vector<vector<int>>ans=searchWord(grid,word);printResult(ans);}
Java
importjava.util.ArrayList;classSolution{publicbooleanvalidCoord(intx,inty,intm,intn){return(x>=0&&x<m&&y>=0&&y<n);}publicbooleanfindWord(intindex,Stringword,char[][]grid,intx,inty,intdirX,intdirY){// If word has been foundif(index==word.length()){returntrue;}// If the current coordinate is valid and characters match,// then check the next indexif(validCoord(x,y,grid.length,grid[0].length)&&word.charAt(index)==grid[x][y]){returnfindWord(index+1,word,grid,x+dirX,y+dirY,dirX,dirY);}returnfalse;}publicArrayList<ArrayList<Integer>>searchWord(char[][]grid,Stringword){intm=grid.length;intn=grid[0].length;ArrayList<ArrayList<ArrayList<Integer>>>dummy;// optionalArrayList<ArrayList<Integer>>ans=newArrayList<>();// 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(inti=0;i<m;i++){for(intj=0;j<n;j++){// Search in all 8 directionsfor(intk=0;k<8;k++){// If word is found, then append coordinates and breakif(findWord(0,word,grid,i,j,x[k],y[k])){ArrayList<Integer>coord=newArrayList<>();coord.add(i);coord.add(j);ans.add(coord);break;}}}}returnans;}}
Python
defisValid(x,y,sizeX,sizeY):return0<=x<sizeXand0<=y<sizeYdeffindWordInDirection(grid,n,m,word,index,x,y,dirX,dirY):ifindex==len(word):returnTrueifisValid(x,y,n,m)andword[index]==grid[x][y]:returnfindWordInDirection(grid,n,m,word,index+1,x+dirX,y+dirY,dirX,dirY)returnFalsedefsearchWord(grid,word):ans=[]n=len(grid)m=len(grid[0])# Directions for 8 possible movementsdirections=[(1,0),(-1,0),(0,1),(0,-1),(1,1),(1,-1),(-1,1),(-1,-1)]foriinrange(n):forjinrange(m):# Check if the first character matchesifgrid[i][j]==word[0]:fordirX,dirYindirections:iffindWordInDirection(grid,n,m,word,0,i,j,dirX,dirY):ans.append([i,j])breakreturnansdefprintResult(ans):forainans: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#
usingSystem;usingSystem.Collections.Generic;classGFG{publicboolvalidCoord(intx,inty,intm,intn){return(x>=0&&x<m&&y>=0&&y<n);}publicboolfindWord(intindex,stringword,char[][]grid,intx,inty,intdirX,intdirY){// If word has been foundif(index==word.Length){returntrue;}// If the current coordinate is valid and characters match,// then check the next indexif(validCoord(x,y,grid.Length,grid[0].Length)&&word[index]==grid[x][y]){returnfindWord(index+1,word,grid,x+dirX,y+dirY,dirX,dirY);}returnfalse;}// Returns coordinates as List<List<int>> (C# equivalent of ArrayList<ArrayList<Integer>>)publicList<List<int>>searchWord(char[][]grid,stringword){intm=grid.Length;intn=grid[0].Length;List<List<int>>ans=newList<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(inti=0;i<m;i++){for(intj=0;j<n;j++){// Search in all 8 directionsfor(intk=0;k<8;k++){// If word is found, append coordinates and breakif(findWord(0,word,grid,i,j,x[k],y[k])){ans.Add(newList<int>{i,j});break;}}}}returnans;}}
JavaScript
functionvalidCoord(x,y,m,n){return(x>=0&&x<m&&y>=0&&y<n);}functionfindWord(index,word,grid,x,y,dirX,dirY){// if word has been foundif(index===word.length)returntrue;// if the current coordinate is // valid and characters match, then// check the next indexif(validCoord(x,y,grid.length,grid[0].length)&&word[index]===grid[x][y])returnfindWord(index+1,word,grid,x+dirX,y+dirY,dirX,dirY);returnfalse;}functionsearchWord(grid,word){letm=grid.length;letn=grid[0].length;letans=[];// x and y are used to set the direction in which// word needs to be searched.letx=[-1,-1,-1,0,0,1,1,1];lety=[-1,0,1,-1,1,-1,0,1];for(leti=0;i<m;i++){for(letj=0;j<n;j++){// Search in all 8 directionsfor(letk=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;}}}}returnans;}functionprintResult(ans){for(leti=0;i<ans.length;i++){console.log("{"+ans[i][0]+","+ans[i][1]+"}");}}// Driver Codeconstgrid=[['a','b','a','b'],['a','b','e','b'],['e','b','e','b']];constword="abe";constans=searchWord(grid,word);printResult(ans);
Output
{0,0} {0,2} {1,0}
[Expected Approach] Iterative - O(m × n × WordLength) Time and O(1) Space
Start from every cell of the grid and check whether the given word can be formed by moving in any one of the 8 directions. If characters keep matching in a straight direction, the word is found from that starting cell.
Define 8 possible directions using two arrays
Traverse the grid using nested loops. For each cell (i, j) check if it matches the first character of the word
If matches, try each direction, move step by step from the current cell
Compare remaining characters of the word one by one If out of bounds or mismatch occurs, stop that direction
If all characters match, store the cell (i, j) in result if word is found
C++
#include<iostream>usingnamespacestd;boolsearch2D(vector<vector<char>>grid,introw,intcol,stringword){intm=grid.size();intn=grid[0].size();// return false if the given coordinate// does not match with first index char.if(grid[row][col]!=word[0])returnfalse;intlen=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(intdir=0;dir<8;dir++){// Initialize starting point for current directionintk,currX=row+x[dir],currY=col+y[dir];// First character is already checked, match remaining// charactersfor(k=1;k<len;k++){// break if out of boundsif(currX>=m||currX<0||currY>=n||currY<0)break;if(grid[currX][currY]!=word[k])break;// Moving in particular directioncurrX+=x[dir],currY+=y[dir];}// If all character matched, then value of must// be equal to length of wordif(k==len)returntrue;}// if word is not found in any direction,// then return falsereturnfalse;}vector<vector<int>>searchWord(vector<vector<char>>grid,stringword){intm=grid.size();intn=grid[0].size();vector<vector<int>>ans;for(inti=0;i<m;i++){for(intj=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});}}}returnans;}voidprintResult(vector<vector<int>>ans){for(inti=0;i<ans.size();i++){cout<<"{"<<ans[i][0]<<","<<ans[i][1]<<"}"<<" ";}cout<<endl;}intmain(){vector<vector<char>>grid={{'a','b','a','b'},{'a','b','e','b'},{'e','b','e','b'}};stringword="abe";vector<vector<int>>ans=searchWord(grid,word);printResult(ans);}
Java
importjava.util.ArrayList;publicclassGFG{staticbooleansearch2D(char[][]grid,introw,intcol,Stringword){intm=grid.length;intn=grid[0].length;// Return false if the given coordinate does not match the first charif(grid[row][col]!=word.charAt(0)){returnfalse;}intlen=word.length();// x and y are used to set the direction in which word needs to be searchedint[]x={-1,-1,-1,0,0,1,1,1};int[]y={-1,0,1,-1,1,-1,0,1};// Search in all 8 directions one by onefor(intdir=0;dir<8;dir++){intcurrX=row+x[dir];intcurrY=col+y[dir];intk;// First character is already checked, match remaining charactersfor(k=1;k<len;k++){// Break if out of boundsif(currX>=m||currX<0||currY>=n||currY<0){break;}if(grid[currX][currY]!=word.charAt(k)){break;}// Move in the chosen directioncurrX+=x[dir];currY+=y[dir];}// If all characters matchedif(k==len){returntrue;}}returnfalse;}publicstaticArrayList<ArrayList<Integer>>searchWord(char[][]grid,Stringword){intm=grid.length;intn=grid[0].length;ArrayList<ArrayList<Integer>>ans=newArrayList<>();for(inti=0;i<m;i++){for(intj=0;j<n;j++){// If word is found starting from this coordinateif(search2D(grid,i,j,word)){ArrayList<Integer>coord=newArrayList<>();coord.add(i);coord.add(j);ans.add(coord);}}}returnans;}staticvoidprintResult(ArrayList<ArrayList<Integer>>ans){for(inti=0;i<ans.size();i++){System.out.print("{"+ans.get(i).get(0)+","+ans.get(i).get(1)+"} ");}System.out.println();}publicstaticvoidmain(String[]args){char[][]grid={{'a','b','a','b'},{'a','b','e','b'},{'e','b','e','b'}};Stringword="abe";ArrayList<ArrayList<Integer>>ans=searchWord(grid,word);printResult(ans);}}
Python
defsearch2D(grid,row,col,word):m=len(grid)n=len(grid[0])# return false if the given coordinate# does not match with first index char.ifgrid[row][col]!=word[0]:returnFalselenWord=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.fordirinrange(8):# Initialize starting point for current directioncurrX,currY=row+x[dir],col+y[dir]k=1whilek<lenWord:# break if out of boundsifcurrX>=morcurrX<0orcurrY>=norcurrY<0:break# break if characters dont matchifgrid[currX][currY]!=word[k]:break# Moving in particular directioncurrX+=x[dir]currY+=y[dir]k+=1# If all character matched, then value of must# be equal to length of wordifk==lenWord:returnTrue# if word is not found in any direction,# then return falsereturnFalsedefsearchWord(grid,word):m=len(grid)n=len(grid[0])ans=[]foriinrange(m):forjinrange(n):# if the word is found from this coordinate,# then append it to result.ifsearch2D(grid,i,j,word):ans.append((i,j))returnansdefprintResult(ans):forcoordinans: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#
usingSystem;usingSystem.Collections.Generic;publicclassGFG{staticboolsearch2D(char[][]grid,introw,intcol,stringword){intm=grid.Length;intn=grid[0].Length;// Return false if the given coordinate does not match the first charif(grid[row][col]!=word[0]){returnfalse;}intlen=word.Length;// x and y are used to set the direction in which word needs to be searchedint[]x={-1,-1,-1,0,0,1,1,1};int[]y={-1,0,1,-1,1,-1,0,1};// Search in all 8 directions one by onefor(intdir=0;dir<8;dir++){intcurrX=row+x[dir];intcurrY=col+y[dir];intk;// First character is already checked, match remaining charactersfor(k=1;k<len;k++){// Break if out of boundsif(currX>=m||currX<0||currY>=n||currY<0){break;}if(grid[currX][currY]!=word[k]){break;}// Move in the chosen directioncurrX+=x[dir];currY+=y[dir];}// If all characters matchedif(k==len){returntrue;}}returnfalse;}publicstaticList<List<int>>searchWord(char[][]grid,stringword){intm=grid.Length;intn=grid[0].Length;List<List<int>>ans=newList<List<int>>();for(inti=0;i<m;i++){for(intj=0;j<n;j++){// If the word is found starting from this coordinateif(search2D(grid,i,j,word)){ans.Add(newList<int>{i,j});}}}returnans;}staticvoidprintResult(List<List<int>>ans){for(inti=0;i<ans.Count;i++){Console.Write("{"+ans[i][0]+","+ans[i][1]+"} ");}Console.WriteLine();}publicstaticvoidMain(){char[][]grid=newchar[][]{newchar[]{'a','b','a','b'},newchar[]{'a','b','e','b'},newchar[]{'e','b','e','b'}};stringword="abe";List<List<int>>ans=searchWord(grid,word);printResult(ans);}}
JavaScript
functionsearch2D(grid,row,col,word){letm=grid.length;letn=grid[0].length;// return false if the given coordinate// does not match with first index char.if(grid[row][col]!==word[0])returnfalse;letlen=word.length;// x and y are used to set the direction in which// word needs to be searched.letx=[-1,-1,-1,0,0,1,1,1];lety=[-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(letdir=0;dir<8;dir++){// Initialize starting point for current directionletcurrX=row+x[dir],currY=col+y[dir],k=1;// First character is already checked, match remaining// charactersfor(k=1;k<len;k++){// break if out of boundsif(currX>=m||currX<0||currY>=n||currY<0)break;// break if characters dont matchif(grid[currX][currY]!==word[k])break;// Moving in particular directioncurrX+=x[dir];currY+=y[dir];}// If all character matched, then value of must// be equal to length of wordif(k===len)returntrue;}// if word is not found in any direction,// then return falsereturnfalse;}functionsearchWord(grid,word){letm=grid.length;letn=grid[0].length;letans=[];for(leti=0;i<m;i++){for(letj=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]);}}}returnans;}functionprintResult(ans){ans.forEach(coord=>{console.log("{"+coord[0]+","+coord[1]+"}");;});}// Driver Codeletgrid=[['a','b','a','b'],['a','b','e','b'],['e','b','e','b']];letword="abe";letans=searchWord(grid,word);printResult(ans);