Open In App

Boggle (Find all possible words in a board of characters) | Set 1

Last Updated : 23 Jul, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

You are given a list of strings, words[], and an n × m matrix of characters, letters[][]. The objective is to locate all the words from words[] that can be constructed by consecutively linking adjacent characters in the matrix. You are allowed to move in any of the 8 possible directions (horizontally, vertically, or diagonally), but each cell in the matrix can be used only once per word.

Example:

Input: words[] = [ "geeks", "for", "quiz", "go" ]
letters[][] = [[ 'g', 'i', 'z' ],
[ 'u', 'e', 'k' ],
[ 'q', 's', 'e' ]]
Output: geeks quiz
Explanation: To form the word "geeks", begin at cell (0,0) containing 'g'. Next, proceed diagonally down-right to cell (1,1) with 'e', then continue in the same diagonal direction to cell (2,2) for another 'e'. After that, move upward to cell (1,2) to pick up 'k', and finally, go diagonally down-left to cell (2,1) to complete the word with 's'.

Boggle

[Naive Approach] - Using Depth First Search - O(n ^ 2 * m ^ 2) Time and O(n * m) Space

The idea is to treat every cell in the matrix as a potential starting point and generate all words that begin with the cell using depth-first search. For every generated word, check if it is present in the given set of words. If yes, then add it to the result and remove it from the given words to avoid duplicates. During DFS search, it is crucial to maintain a record of visited cells, ensuring that each cell is used only once in forming any given word.

Below is given the implementation:

C++
#include <bits/stdc++.h>
using namespace std;

// function to perform dfs on the grid
void dfs(vector<vector<char>>& letters, 
         vector<vector<bool>>& visited, 
         int i, int j, string &str, 
         unordered_set<string>& wordSet, 
         vector<string>& ans) {

    // check if the current cell is out of bounds
    if (i < 0 || i >= letters.size() ||
        j < 0 || j >= letters[0].size()) {
        return;
    }
    
    // check if the current cell is already visited
    if (visited[i][j]) {
        return;
    }
    
    // mark the current cell as visited
    visited[i][j] = true;
    
    // add the current character to the string
    str += letters[i][j];
    
    // check if the current string is in the wordSet
    if (wordSet.find(str) != wordSet.end()) {
        ans.push_back(str);

        // remove the word from the set to avoid duplicates
        wordSet.erase(str); 
    }
    
    // perform dfs on all 8 directions
    for (int row = -1; row <= 1; row++) {
        for (int col = -1; col <= 1; col++) {

            // skip the current cell
            if (row == 0 && col == 0) continue; 
            dfs(letters, visited, i + row, 
            j + col, str, wordSet, ans);
        }
    }
    
    // backtrack and unmark the current cell as visited
    visited[i][j] = false;

    // remove the last character from the string
    str.pop_back();
}

// find all words in a given grid of characters
// and a given dictionary
vector<string> findWords(vector<string>& words, 
                         vector<vector<char>>& letters) {
    int n = letters.size(), m = letters[0].size();
    vector<string> ans;
    
    // store the words in the hashSet
    unordered_set<string> wordSet(words.begin(), words.end());
    
    // to mark the cell visited
    vector<vector<bool>> visited(n, vector<bool>(m, false));

    // perform dfs on each cell of the grid
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            string str = "";
            dfs(letters, visited, i, j, str, wordSet, ans);
        }
    }

    return ans;
}

int main() {
    vector<string> words = {"geeks", "for", "quiz", "go"};
    vector<vector<char>> letters = {
        {'g', 'i', 'z'},
        {'u', 'e', 'k'},
        {'q', 's', 'e'}
    };
    vector<string> ans = findWords(words, letters);
    for (string word : ans) {
        cout << word << " ";
    }
    return 0;
}
Java
import java.util.*;

class GfG {

    // function to perform dfs on the grid
    static void dfs(char[][] letters, 
            boolean[][] visited, 
            int i, int j, StringBuilder str, 
            Set<String> wordSet, 
            List<String> ans) {

        // check if the current cell is out of bounds
        if (i < 0 || i >= letters.length ||
            j < 0 || j >= letters[0].length) {
            return;
        }

        // check if the current cell is already visited
        if (visited[i][j]) {
            return;
        }

        // mark the current cell as visited
        visited[i][j] = true;

        // add the current character to the string
        str.append(letters[i][j]);

        // check if the current string is in the wordSet
        if (wordSet.contains(str.toString())) {
            ans.add(str.toString());

            // remove the word from the set to avoid duplicates
            wordSet.remove(str.toString()); 
        }

        // perform dfs on all 8 directions
        for (int row = -1; row <= 1; row++) {
            for (int col = -1; col <= 1; col++) {

                // skip the current cell
                if (row == 0 && col == 0) continue;
                dfs(letters, visited, i + row, 
                j + col, str, wordSet, ans);
            }
        }

        // backtrack and unmark the current cell as visited
        visited[i][j] = false;

        // remove the last character from the string
        str.deleteCharAt(str.length() - 1);
    }

    // find all words in a given grid of characters
    // and a given dictionary
    static List<String> findWords(List<String> words, 
            char[][] letters) {
        int n = letters.length, m = letters[0].length;
        List<String> ans = new ArrayList<>();

        // store the words in the hashSet
        Set<String> wordSet = new HashSet<>(words);

        // to mark the cell visited
        boolean[][] visited = new boolean[n][m];

        // perform dfs on each cell of the grid
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                StringBuilder str = new StringBuilder();
                dfs(letters, visited, i, j, str, wordSet, ans);
            }
        }

        return ans;
    }

    public static void main(String[] args) {
        List<String> words = Arrays.asList("geeks", "for", "quiz", "go");
        char[][] letters = {
            {'g', 'i', 'z'},
            {'u', 'e', 'k'},
            {'q', 's', 'e'}
        };
        List<String> ans = findWords(words, letters);
        for (String word : ans) {
            System.out.print(word + " ");
        }
    }
}
Python
# function to perform dfs on the grid
def dfs(letters, visited, i, j, str, wordSet, ans):

    # check if the current cell is out of bounds
    if i < 0 or i >= len(letters) or j < 0 or j >= len(letters[0]):
        return

    # check if the current cell is already visited
    if visited[i][j]:
        return

    # mark the current cell as visited
    visited[i][j] = True

    # add the current character to the string
    str += letters[i][j]

    # check if the current string is in the wordSet
    if str in wordSet:
        ans.append(str)

        # remove the word from the set to avoid duplicates
        wordSet.remove(str)

    # perform dfs on all 8 directions
    for row in range(-1, 2):
        for col in range(-1, 2):

            # skip the current cell
            if row == 0 and col == 0:
                continue
            dfs(letters, visited, i + row, j + col, str, wordSet, ans)

    # backtrack and unmark the current cell as visited
    visited[i][j] = False

    # remove the last character from the string
    str = str[:-1]

# find all words in a given grid of characters
# and a given dictionary
def findWords(words, letters):
    n, m = len(letters), len(letters[0])
    ans = []

    # store the words in the hashSet
    wordSet = set(words)

    # to mark the cell visited
    visited = [[False for _ in range(m)] for _ in range(n)]

    # perform dfs on each cell of the grid
    for i in range(n):
        for j in range(m):
            dfs(letters, visited, i, j, "", wordSet, ans)

    return ans

words = ["geeks", "for", "quiz", "go"]
letters = [
    ['g', 'i', 'z'],
    ['u', 'e', 'k'],
    ['q', 's', 'e']
]
ans = findWords(words, letters)
for word in ans:
    print(word, end=" ")
C#
using System;
using System.Collections.Generic;

class GfG {

    // function to perform dfs on the grid
    static void dfs(char[,] letters, 
            bool[,] visited, 
            int i, int j, string str, 
            HashSet<string> wordSet, 
            List<string> ans) {

        // check if the current cell is out of bounds
        if (i < 0 || i >= letters.GetLength(0) ||
            j < 0 || j >= letters.GetLength(1)) {
            return;
        }

        // check if the current cell is already visited
        if (visited[i, j]) {
            return;
        }

        // mark the current cell as visited
        visited[i, j] = true;

        // add the current character to the string
        str += letters[i, j];

        // check if the current string is in the wordSet
        if (wordSet.Contains(str)) {
            ans.Add(str);

            // remove the word from the set to avoid duplicates
            wordSet.Remove(str);
        }

        // perform dfs on all 8 directions
        for (int row = -1; row <= 1; row++) {
            for (int col = -1; col <= 1; col++) {

                // skip the current cell
                if (row == 0 && col == 0) continue;
                dfs(letters, visited, i + row, 
                j + col, str, wordSet, ans);
            }
        }

        // backtrack and unmark the current cell as visited
        visited[i, j] = false;

        // remove the last character from the string
        str = str.Substring(0, str.Length - 1);
    }

    // find all words in a given grid of characters
    // and a given dictionary
    static List<string> findWords(List<string> words, 
            char[,] letters) {
        int n = letters.GetLength(0), m = letters.GetLength(1);
        List<string> ans = new List<string>();

        // store the words in the hashSet
        HashSet<string> wordSet = new HashSet<string>(words);

        // to mark the cell visited
        bool[,] visited = new bool[n, m];

        // perform dfs on each cell of the grid
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                dfs(letters, visited, i, j, "", wordSet, ans);
            }
        }

        return ans;
    }

    static void Main() {
        List<string> words = new List<string>{"geeks", "for", "quiz", "go"};
        char[,] letters = {
            {'g', 'i', 'z'},
            {'u', 'e', 'k'},
            {'q', 's', 'e'}
        };
        List<string> ans = findWords(words, letters);
        foreach (string word in ans) {
            Console.Write(word + " ");
        }
    }
}
JavaScript
// function to perform dfs on the grid
function dfs(letters, visited, i, j, str, wordSet, ans) {

    // check if the current cell is out of bounds
    if (i < 0 || i >= letters.length || j < 0 || j >= letters[0].length) {
        return;
    }

    // check if the current cell is already visited
    if (visited[i][j]) {
        return;
    }

    // mark the current cell as visited
    visited[i][j] = true;

    // add the current character to the string
    str += letters[i][j];

    // check if the current string is in the wordSet
    if (wordSet.has(str)) {
        ans.push(str);

        // remove the word from the set to avoid duplicates
        wordSet.delete(str);
    }

    // perform dfs on all 8 directions
    for (let row = -1; row <= 1; row++) {
        for (let col = -1; col <= 1; col++) {

            // skip the current cell
            if (row === 0 && col === 0) continue;
            dfs(letters, visited, i + row, j + col, str, wordSet, ans);
        }
    }

    // backtrack and unmark the current cell as visited
    visited[i][j] = false;

    // remove the last character from the string
    str = str.slice(0, -1);
}

// find all words in a given grid of characters
// and a given dictionary
function findWords(words, letters) {
    const n = letters.length, m = letters[0].length;
    const ans = [];

    // store the words in the hashSet
    const wordSet = new Set(words);

    // to mark the cell visited
    const visited = Array.from({ length: n }, () => Array(m).fill(false));

    // perform dfs on each cell of the grid
    for (let i = 0; i < n; i++) {
        for (let j = 0; j < m; j++) {
            dfs(letters, visited, i, j, "", wordSet, ans);
        }
    }

    return ans;
}

const words = ["geeks", "for", "quiz", "go"];
const letters = [
    ['g', 'i', 'z'],
    ['u', 'e', 'k'],
    ['q', 's', 'e']
];
const ans = findWords(words, letters);
console.log(ans.join(" "));

Output
geeks quiz 

[Better Approach] - Using Depth First Search - O(n * m + r * c) Time and O(n * m) Space

Instead of generating all strings from the grid and then checking whether it exists in dictionary or not , we can simply run a DFS on all words present in dictionary and check whether we can make that word from grid or not.

Below is given the implementation:

C++
#include <bits/stdc++.h>
using namespace std;

// function to perform dfs on the grid
bool dfs(vector<vector<char>>& letters, 
        string word, int i, int j, int index) {

    // check if the current cell is out of bounds
    if (i < 0 || i >= letters.size() || j < 0 || j >= letters[0].size()) {
        return false;
    }
    
    // check if the current cell matches 
    // the character in the word
    if (letters[i][j] != word[index]) {
        return false;
    }
    
    // check if we have found the complete word
    if (index == word.size() - 1) {
        return true;
    }
    
    // mark the current cell as visited
    char temp = letters[i][j];
    letters[i][j] = '#';
    
    // perform dfs on all 8 directions
    for(int row = -1; row <= 1; row++) {
        for (int col = -1; col <= 1; col++) {

            // skip the current cell
            if (row == 0 && col == 0) continue; 
            if (dfs(letters, word, i + row, j + col, index + 1)) {

                // unmark the current cell as visited
                letters[i][j] = temp;
                return true;
            }
        }
    }
    
    // unmark the current cell as visited
    letters[i][j] = temp;
    
    return false;
}

// find all words in a given grid of characters
// and a given dictionary
vector<string> findWords(vector<string>& words, 
                    vector<vector<char>>& letters) {
    int n = letters.size(), m = letters[0].size();
    int r = words.size();
    vector<string> ans;
    
    // store the unique words in the hashSet
    unordered_set<string> result;
                        
    for(int i = 0; i < r; i++) {
        for(int j = 0; j < n; j++) {
            for(int k = 0; k < m; k++) {
                if(dfs(letters, words[i], j, k, 0)) {
                    result.insert(words[i]);
                }
            }
        }
    }

    // convert the set to vector
    for(auto word : result) {
        ans.push_back(word);
    }
    return ans;
}

int main() {
    vector<string> words = {"geeks", "for", "quiz", "go"};
    vector<vector<char>> letters = {
        {'g', 'i', 'z'},
        {'u', 'e', 'k'},
        {'q', 's', 'e'}
    };
    vector<string> ans = findWords(words, letters);
    for (string word : ans) {
        cout << word << " ";
    }
    return 0;
}
Java
import java.util.*;

class GfG {

    // function to perform dfs on the grid
    static boolean dfs(char[][] letters, 
                       String word, int i, int j, int index) {

        // check if the current cell is out of bounds
        if (i < 0 || i >= letters.length || j < 0 || j >= letters[0].length) {
            return false;
        }

        // check if the current cell matches 
        // the character in the word
        if (letters[i][j] != word.charAt(index)) {
            return false;
        }

        // check if we have found the complete word
        if (index == word.length() - 1) {
            return true;
        }

        // mark the current cell as visited
        char temp = letters[i][j];
        letters[i][j] = '#';

        // perform dfs on all 8 directions
        for (int row = -1; row <= 1; row++) {
            for (int col = -1; col <= 1; col++) {

                // skip the current cell
                if (row == 0 && col == 0) continue;
                if (dfs(letters, word, i + row, j + col, index + 1)) {

                    // unmark the current cell as visited
                    letters[i][j] = temp;
                    return true;
                }
            }
        }

        // unmark the current cell as visited
        letters[i][j] = temp;

        return false;
    }

    // find all words in a given grid of characters
    // and a given dictionary
    static List<String> findWords(List<String> words, 
                                  char[][] letters) {
        int n = letters.length, m = letters[0].length;
        int r = words.size();
        List<String> ans = new ArrayList<>();

        // store the unique words in the hashSet
        Set<String> result = new HashSet<>();

        for (int i = 0; i < r; i++) {
            for (int j = 0; j < n; j++) {
                for (int k = 0; k < m; k++) {
                    if (dfs(letters, words.get(i), j, k, 0)) {
                        result.add(words.get(i));
                    }
                }
            }
        }

        // convert the set to vector
        for (String word : result) {
            ans.add(word);
        }

        return ans;
    }

    public static void main(String[] args) {
        List<String> words = Arrays.asList("geeks", "for", "quiz", "go");
        char[][] letters = {
            {'g', 'i', 'z'},
            {'u', 'e', 'k'},
            {'q', 's', 'e'}
        };
        List<String> ans = findWords(words, letters);
        for (String word : ans) {
            System.out.print(word + " ");
        }
    }
}
Python
# function to perform dfs on the grid
def dfs(letters, word, i, j, index):

    # check if the current cell is out of bounds
    if i < 0 or i >= len(letters) or j < 0 or j >= len(letters[0]):
        return False

    # check if the current cell matches 
    # the character in the word
    if letters[i][j] != word[index]:
        return False

    # check if we have found the complete word
    if index == len(word) - 1:
        return True

    # mark the current cell as visited
    temp = letters[i][j]
    letters[i][j] = '#'

    # perform dfs on all 8 directions
    for row in range(-1, 2):
        for col in range(-1, 2):

            # skip the current cell
            if row == 0 and col == 0:
                continue
            if dfs(letters, word, i + row, j + col, index + 1):

                # unmark the current cell as visited
                letters[i][j] = temp
                return True

    # unmark the current cell as visited
    letters[i][j] = temp

    return False

# find all words in a given grid of characters
# and a given dictionary
def findWords(words, letters):
    n, m = len(letters), len(letters[0])
    r = len(words)
    ans = []

    # store the unique words in the hashSet
    result = set()

    for i in range(r):
        for j in range(n):
            for k in range(m):
                if dfs(letters, words[i], j, k, 0):
                    result.add(words[i])

    # convert the set to vector
    for word in result:
        ans.append(word)

    return ans

words = ["geeks", "for", "quiz", "go"]
letters = [
    ['g', 'i', 'z'],
    ['u', 'e', 'k'],
    ['q', 's', 'e']
]
ans = findWords(words, letters)
for word in ans:
    print(word, end=' ')
C#
using System;
using System.Collections.Generic;

class GfG {

    // function to perform dfs on the grid
    static bool dfs(char[][] letters, 
                   string word, int i, int j, int index) {

        // check if the current cell is out of bounds
        if (i < 0 || i >= letters.Length || j < 0 
            || j >= letters[0].Length) {
            return false;
        }

        // check if the current cell matches 
        // the character in the word
        if (letters[i][j] != word[index]) {
            return false;
        }

        // check if we have found the complete word
        if (index == word.Length - 1) {
            return true;
        }

        // mark the current cell as visited
        char temp = letters[i][j];
        letters[i][j] = '#';

        // perform dfs on all 8 directions
        for (int row = -1; row <= 1; row++) {
            for (int col = -1; col <= 1; col++) {

                // skip the current cell
                if (row == 0 && col == 0) continue;
                if (dfs(letters, word, i + row, j + col, index + 1)) {

                    // unmark the current cell as visited
                    letters[i][j] = temp;
                    return true;
                }
            }
        }

        // unmark the current cell as visited
        letters[i][j] = temp;

        return false;
    }

    // find all words in a given grid of characters
    // and a given dictionary
    static List<string> findWords(List<string> words, 
                                  char[][] letters) {
        int n = letters.Length, m = letters[0].Length;
        int r = words.Count;
        List<string> ans = new List<string>();

        // store the unique words in the hashSet
        HashSet<string> result = new HashSet<string>();

        for (int i = 0; i < r; i++) {
            for (int j = 0; j < n; j++) {
                for (int k = 0; k < m; k++) {
                    if (dfs(letters, words[i], j, k, 0)) {
                        result.Add(words[i]);
                    }
                }
            }
        }

        // convert the set to vector
        foreach (string word in result) {
            ans.Add(word);
        }

        return ans;
    }

    static void Main() {
        List<string> words = new List<string>{"geeks", "for", "quiz", "go"};
        char[][] letters = {
            new char[]{'g', 'i', 'z'},
            new char[]{'u', 'e', 'k'},
            new char[]{'q', 's', 'e'}
        };
        List<string> ans = findWords(words, letters);
        foreach (string word in ans) {
            Console.Write(word + " ");
        }
    }
}
JavaScript
// function to perform dfs on the grid
function dfs(letters, word, i, j, index) {

    // check if the current cell is out of bounds
    if (i < 0 || i >= letters.length || j < 0 || j >= letters[0].length) {
        return false;
    }

    // check if the current cell matches 
    // the character in the word
    if (letters[i][j] !== word[index]) {
        return false;
    }

    // check if we have found the complete word
    if (index === word.length - 1) {
        return true;
    }

    // mark the current cell as visited
    let temp = letters[i][j];
    letters[i][j] = '#';

    // perform dfs on all 8 directions
    for (let row = -1; row <= 1; row++) {
        for (let col = -1; col <= 1; col++) {

            // skip the current cell
            if (row === 0 && col === 0) continue;
            if (dfs(letters, word, i + row, j + col, index + 1)) {

                // unmark the current cell as visited
                letters[i][j] = temp;
                return true;
            }
        }
    }

    // unmark the current cell as visited
    letters[i][j] = temp;

    return false;
}

// find all words in a given grid of characters
// and a given dictionary
function findWords(words, letters) {
    let n = letters.length, m = letters[0].length;
    let r = words.length;
    let ans = [];

    // store the unique words in the hashSet
    let result = new Set();

    for (let i = 0; i < r; i++) {
        for (let j = 0; j < n; j++) {
            for (let k = 0; k < m; k++) {
                if (dfs(letters, words[i], j, k, 0)) {
                    result.add(words[i]);
                }
            }
        }
    }

    // convert the set to vector
    for (let word of result) {
        ans.push(word);
    }

    return ans;
}

let words = ["geeks", "for", "quiz", "go"];
let letters = [
    ['g', 'i', 'z'],
    ['u', 'e', 'k'],
    ['q', 's', 'e']
];
let ans = findWords(words, letters);
for (let word of ans) {
    process.stdout.write(word + " ");
}

Output
quiz geeks 

Related Article:


Article Tags :
Practice Tags :

Similar Reads