Grid Word Search in 8 Directions (original) (raw)
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]]
Table of Content
- [Naive Search] Recursion - O(m × n × WordLength) Time and O(L) Space
- [Expected Approach] Iterative - O(m × n × WordLength) Time and O(1) Space
[Naive Search] 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 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> &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>searchWord(vector<vector>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> ans) { for (int i=0; i<ans.size(); i++) { cout << "{" << ans[i][0] << "," << ans[i][1] << "}" << " "; } cout<<endl; }
int main() { vector<vector> 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
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
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 Falsedef 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 ansdef 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#
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
// 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] + "}"); } }
// Driver Code const grid = [ ['a', 'b', 'a', 'b'], ['a', 'b', 'e', 'b'], ['e', 'b', 'e', 'b'] ]; const word = "abe";
const ans = searchWord(grid, word);
printResult(ans);
`
[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 using namespace std;
// This function searches for the given word // in all 8 directions from the coordinate. bool search2D(vector<vector> 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>searchWord(vector<vector>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> ans) { for (int i=0; i<ans.size(); i++) { cout << "{" << ans[i][0] << "," << ans[i][1] << "}" << " "; } cout<<endl; }
int main() { vector<vector> 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
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
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 FalseThis 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 ansdef 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#
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
// 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] + "}");; }); }
// Driver Code let grid = [ ['a', 'b', 'a', 'b'], ['a', 'b', 'e', 'b'], ['e', 'b', 'e', 'b'] ]; let word = "abe";
let ans = searchWord(grid, word); printResult(ans);
`

