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

Last Updated : 23 Jul, 2025

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

Try It Yourselfredirect icon

Table of Content

[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>& letters, vector<vector>& visited, int i, int j, string &str, unordered_set& wordSet, vector& 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 findWords(vector& words, vector<vector>& letters) { int n = letters.size(), m = letters[0].size(); vector 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 words = {"geeks", "for", "quiz", "go"}; vector<vector> letters = { {'g', 'i', 'z'}, {'u', 'e', 'k'}, {'q', 's', 'e'} }; vector 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(" "));

`

[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>& 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 findWords(vector& words, vector<vector>& letters) { int n = letters.size(), m = letters[0].size(); int r = words.size(); vector 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 words = {"geeks", "for", "quiz", "go"}; vector<vector> letters = { {'g', 'i', 'z'}, {'u', 'e', 'k'}, {'q', 's', 'e'} }; vector 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 + " "); }

`

**Related Article: