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]]

ex-3_1

**Input:
grid = [[a,b,a,b],[a,b,e,b],[e,b,e,b]]
word = "abe"
**Output:
[[0,0[,[0,2],[1,0]]

2222

Table of Content

[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.

#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 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#

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.

#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 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#

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);

`