Given a dictionary, a method to do a lookup in the dictionary and a M x N board where every cell has one character. Find all possible words that can be formed by a sequence of adjacent characters. Note that we can move to any of 8 adjacent characters, but a word should not have multiple instances of the same cell.
Example:
Input: dictionary[] = {"GEEKS", "FOR", "QUIZ", "GO"}; boggle[][] = {{'G', 'I', 'Z'}, {'U', 'E', 'K'}, {'Q', 'S', 'E'}}; Output: Following words of the dictionary are present GEEKS QUIZ Explanation:
Input: dictionary[] = {"GEEKS", "ABCFIHGDE"}; boggle[][] = {{'A', 'B', 'C'}, {'D', 'E', 'F'}, {'G', 'H', 'I'}}; Output: Following words of the dictionary are present ABCFIHGDE Explanation:
We have discussed a Graph DFS based solution in below post.
Boggle (Find all possible words in a board of characters) | Set 1
Here we discuss a Trie based solution which is better than DFS based solution.
Given Dictionary dictionary[] = {“GEEKS”, “FOR”, “QUIZ”, “GO”}
1. Create an Empty trie and insert all words of given dictionary into trie
After insertion, Trie looks like(leaf nodes are in RED) root / G F Q / | | | O E O U | | | E R I | | K Z | S
2. After that we have pick only those character in boggle[][] which are child of root of Trie
Let for above we pick ‘G’ boggle[0][0], ‘Q’ boggle[2][0] (they both are present in boggle matrix)
3. search a word in a trie which start with character that we pick in step 2
1) Create bool visited boolean matrix (Visited[M][N] = false ) 2) Call SearchWord() for every cell (i, j) which has one of the first characters of dictionary words. In above example, we have 'G' and 'Q' as first characters. SearchWord(Trie *root, i, j, visited[][N]) if root->leaf == true print word if we have seen this element first time then make it visited. visited[i][j] = true do traverse all child of current root k goes (0 to 26 ) [there are only 26 Alphabet] add current char and search for next character find next character which is adjacent to boggle[i][j] they are 8 adjacent cells of boggle[i][j] (i+1, j+1), (i+1, j) (i-1, j) and so on. make it unvisited visited[i][j] = false
Below is the implementation of above idea:
// C++ program for Boggle game #include <bits/stdc++.h> using namespace std;
// Converts key current character into index // use only 'A' through 'Z' #define char_int(c) ((int)c - (int)'A') // Alphabet size #define SIZE (26) #define M 3 #define N 3 // trie Node struct TrieNode {
TrieNode* Child[SIZE];
// isLeaf is true if the node represents
// end of a word
bool leaf;
}; // Returns new trie node (initialized to NULLs) TrieNode* getNode() { TrieNode* newNode = new TrieNode;
newNode->leaf = false ;
for ( int i = 0; i < SIZE; i++)
newNode->Child[i] = NULL;
return newNode;
} // If not present, inserts a key into the trie // If the key is a prefix of trie node, just // marks leaf node void insert(TrieNode* root, char * Key)
{ int n = strlen (Key);
TrieNode* pChild = root;
for ( int i = 0; i < n; i++) {
int index = char_int(Key[i]);
if (pChild->Child[index] == NULL)
pChild->Child[index] = getNode();
pChild = pChild->Child[index];
}
// make last node as leaf node
pChild->leaf = true ;
} // function to check that current location // (i and j) is in matrix range bool isSafe( int i, int j, bool visited[M][N])
{ return (i >= 0 && i < M && j >= 0 && j < N && !visited[i][j]);
} // A recursive function to print all words present on boggle void searchWord(TrieNode* root, char boggle[M][N], int i,
int j, bool visited[][N], string str)
{ // if we found word in trie / dictionary
if (root->leaf == true )
cout << str << endl;
// If both I and j in range and we visited
// that element of matrix first time
if (isSafe(i, j, visited)) {
// make it visited
visited[i][j] = true ;
// traverse all childs of current root
for ( int K = 0; K < SIZE; K++) {
if (root->Child[K] != NULL) {
// current character
char ch = ( char )K + ( char ) 'A' ;
// Recursively search reaming character of word
// in trie for all 8 adjacent cells of boggle[i][j]
if (isSafe(i + 1, j + 1, visited)
&& boggle[i + 1][j + 1] == ch)
searchWord(root->Child[K], boggle,
i + 1, j + 1, visited, str + ch);
if (isSafe(i, j + 1, visited)
&& boggle[i][j + 1] == ch)
searchWord(root->Child[K], boggle,
i, j + 1, visited, str + ch);
if (isSafe(i - 1, j + 1, visited)
&& boggle[i - 1][j + 1] == ch)
searchWord(root->Child[K], boggle,
i - 1, j + 1, visited, str + ch);
if (isSafe(i + 1, j, visited)
&& boggle[i + 1][j] == ch)
searchWord(root->Child[K], boggle,
i + 1, j, visited, str + ch);
if (isSafe(i + 1, j - 1, visited)
&& boggle[i + 1][j - 1] == ch)
searchWord(root->Child[K], boggle,
i + 1, j - 1, visited, str + ch);
if (isSafe(i, j - 1, visited)
&& boggle[i][j - 1] == ch)
searchWord(root->Child[K], boggle,
i, j - 1, visited, str + ch);
if (isSafe(i - 1, j - 1, visited)
&& boggle[i - 1][j - 1] == ch)
searchWord(root->Child[K], boggle,
i - 1, j - 1, visited, str + ch);
if (isSafe(i - 1, j, visited)
&& boggle[i - 1][j] == ch)
searchWord(root->Child[K], boggle,
i - 1, j, visited, str + ch);
}
}
// make current element unvisited
visited[i][j] = false ;
}
} // Prints all words present in dictionary. void findWords( char boggle[M][N], TrieNode* root)
{ // Mark all characters as not visited
bool visited[M][N];
memset (visited, false , sizeof (visited));
TrieNode* pChild = root;
string str = "" ;
// traverse all matrix elements
for ( int i = 0; i < M; i++) {
for ( int j = 0; j < N; j++) {
// we start searching for word in dictionary
// if we found a character which is child
// of Trie root
if (pChild->Child[char_int(boggle[i][j])]) {
str = str + boggle[i][j];
searchWord(pChild->Child[char_int(boggle[i][j])],
boggle, i, j, visited, str);
str = "" ;
}
}
}
} // Driver program to test above function int main()
{ // Let the given dictionary be following
char * dictionary[] = { "GEEKS" , "FOR" , "QUIZ" , "GEE" };
// root Node of trie
TrieNode* root = getNode();
// insert all words of dictionary into trie
int n = sizeof (dictionary) / sizeof (dictionary[0]);
for ( int i = 0; i < n; i++)
insert(root, dictionary[i]);
char boggle[M][N] = { { 'G' , 'I' , 'Z' },
{ 'U' , 'E' , 'K' },
{ 'Q' , 'S' , 'E' } };
findWords(boggle, root);
return 0;
} |
// Java program for Boggle game public class Boggle {
// Alphabet size
static final int SIZE = 26 ;
static final int M = 3 ;
static final int N = 3 ;
// trie Node
static class TrieNode {
TrieNode[] Child = new TrieNode[SIZE];
// isLeaf is true if the node represents
// end of a word
boolean leaf;
// constructor
public TrieNode()
{
leaf = false ;
for ( int i = 0 ; i < SIZE; i++)
Child[i] = null ;
}
}
// If not present, inserts a key into the trie
// If the key is a prefix of trie node, just
// marks leaf node
static void insert(TrieNode root, String Key)
{
int n = Key.length();
TrieNode pChild = root;
for ( int i = 0 ; i < n; i++) {
int index = Key.charAt(i) - 'A' ;
if (pChild.Child[index] == null )
pChild.Child[index] = new TrieNode();
pChild = pChild.Child[index];
}
// make last node as leaf node
pChild.leaf = true ;
}
// function to check that current location
// (i and j) is in matrix range
static boolean isSafe( int i, int j, boolean visited[][])
{
return (i >= 0 && i < M && j >= 0
&& j < N && !visited[i][j]);
}
// A recursive function to print
// all words present on boggle
static void searchWord(TrieNode root, char boggle[][], int i,
int j, boolean visited[][], String str)
{
// if we found word in trie / dictionary
if (root.leaf == true )
System.out.println(str);
// If both I and j in range and we visited
// that element of matrix first time
if (isSafe(i, j, visited)) {
// make it visited
visited[i][j] = true ;
// traverse all child of current root
for ( int K = 0 ; K < SIZE; K++) {
if (root.Child[K] != null ) {
// current character
char ch = ( char )(K + 'A' );
// Recursively search reaming character of word
// in trie for all 8 adjacent cells of
// boggle[i][j]
if (isSafe(i + 1 , j + 1 , visited)
&& boggle[i + 1 ][j + 1 ] == ch)
searchWord(root.Child[K], boggle,
i + 1 , j + 1 ,
visited, str + ch);
if (isSafe(i, j + 1 , visited)
&& boggle[i][j + 1 ] == ch)
searchWord(root.Child[K], boggle,
i, j + 1 ,
visited, str + ch);
if (isSafe(i - 1 , j + 1 , visited)
&& boggle[i - 1 ][j + 1 ] == ch)
searchWord(root.Child[K], boggle,
i - 1 , j + 1 ,
visited, str + ch);
if (isSafe(i + 1 , j, visited)
&& boggle[i + 1 ][j] == ch)
searchWord(root.Child[K], boggle,
i + 1 , j,
visited, str + ch);
if (isSafe(i + 1 , j - 1 , visited)
&& boggle[i + 1 ][j - 1 ] == ch)
searchWord(root.Child[K], boggle,
i + 1 , j - 1 ,
visited, str + ch);
if (isSafe(i, j - 1 , visited)
&& boggle[i][j - 1 ] == ch)
searchWord(root.Child[K], boggle,
i, j - 1 ,
visited, str + ch);
if (isSafe(i - 1 , j - 1 , visited)
&& boggle[i - 1 ][j - 1 ] == ch)
searchWord(root.Child[K], boggle,
i - 1 , j - 1 ,
visited, str + ch);
if (isSafe(i - 1 , j, visited)
&& boggle[i - 1 ][j] == ch)
searchWord(root.Child[K], boggle,
i - 1 , j,
visited, str + ch);
}
}
// make current element unvisited
visited[i][j] = false ;
}
}
// Prints all words present in dictionary.
static void findWords( char boggle[][], TrieNode root)
{
// Mark all characters as not visited
boolean [][] visited = new boolean [M][N];
TrieNode pChild = root;
String str = "" ;
// traverse all matrix elements
for ( int i = 0 ; i < M; i++) {
for ( int j = 0 ; j < N; j++) {
// we start searching for word in dictionary
// if we found a character which is child
// of Trie root
if (pChild.Child[(boggle[i][j]) - 'A' ] != null ) {
str = str + boggle[i][j];
searchWord(pChild.Child[(boggle[i][j]) - 'A' ],
boggle, i, j, visited, str);
str = "" ;
}
}
}
}
// Driver program to test above function
public static void main(String args[])
{
// Let the given dictionary be following
String dictionary[] = { "GEEKS" , "FOR" , "QUIZ" , "GEE" };
// root Node of trie
TrieNode root = new TrieNode();
// insert all words of dictionary into trie
int n = dictionary.length;
for ( int i = 0 ; i < n; i++)
insert(root, dictionary[i]);
char boggle[][] = { { 'G' , 'I' , 'Z' },
{ 'U' , 'E' , 'K' },
{ 'Q' , 'S' , 'E' } };
findWords(boggle, root);
}
} // This code is contributed by Sumit Ghosh |
# Python program for Boggle game class TrieNode:
# Trie node class
def __init__( self ):
self .children = [ None ] * 26
# isEndOfWord is True if node represent the end of the word
self .isEndOfWord = False
M = 3
N = 3
class Boogle:
# Trie data structure class
def __init__( self ):
self .root = self .getNode()
def getNode( self ):
# Returns new trie node (initialized to NULLs)
return TrieNode()
def _charToIndex( self , ch):
# private helper function
# Converts key current character into index
# use only 'A' through 'Z' and upper case
return ord (ch) - ord ( 'A' )
def insert( self , key):
# If not present, inserts key into trie
# If the key is prefix of trie node,
# just marks leaf node
pCrawl = self .root
length = len (key)
for level in range (length):
index = self ._charToIndex(key[level])
# if current character is not present
if not pCrawl.children[index]:
pCrawl.children[index] = self .getNode()
pCrawl = pCrawl.children[index]
# print('h', self.root.children)
# mark last node as leaf
pCrawl.isEndOfWord = True
def is_Safe(i, j, vis):
return 0 < = i < M and 0 < = j < N and not vis[i][j]
def search_word(root, boggle, i, j, vis, string):
if root.isEndOfWord:
print (string)
if is_Safe(i, j, vis):
vis[i][j] = True
for K in range ( 26 ):
if root.children[K] is not None :
ch = chr (K + ord ( 'A' ))
# Recursively search reaming character of word
# in trie for all 8 adjacent cells of boggle[i][j]
if is_Safe(i + 1 , j + 1 , vis) and boggle[i + 1 ][j + 1 ] = = ch:
search_word(root.children[K], boggle,
i + 1 , j + 1 , vis, string + ch)
if is_Safe(i, j + 1 , vis) and boggle[i][j + 1 ] = = ch:
search_word(root.children[K], boggle,
i, j + 1 , vis, string + ch)
if is_Safe(i - 1 , j + 1 , vis) and boggle[i - 1 ][j + 1 ] = = ch:
search_word(root.children[K], boggle,
i - 1 , j + 1 , vis, string + ch)
if is_Safe(i + 1 , j, vis) and boggle[i + 1 ][j] = = ch:
search_word(root.children[K], boggle,
i + 1 , j, vis, string + ch)
if is_Safe(i + 1 , j - 1 , vis) and boggle[i + 1 ][j - 1 ] = = ch:
search_word(root.children[K], boggle,
i + 1 , j - 1 , vis, string + ch)
if is_Safe(i, j - 1 , vis) and boggle[i][j - 1 ] = = ch:
search_word(root.children[K], boggle,
i, j - 1 , vis, string + ch)
if is_Safe(i - 1 , j - 1 , vis) and boggle[i - 1 ][j - 1 ] = = ch:
search_word(root.children[K], boggle,
i - 1 , j - 1 , vis, string + ch)
if is_Safe(i - 1 , j, vis) and boggle[i - 1 ][j] = = ch:
search_word(root.children[K], boggle,
i - 1 , j, vis, string + ch)
vis[i][j] = False
def char_int(ch):
# private helper function
# Converts key current character into index
# use only 'A' through 'Z' and upper case
return ord (ch) - ord ( 'A' )
def findWords(boggle, root):
# Mark all characters as not visited
visited = [[ False for i in range (N)] for i in range (M)]
pChild = root
string = ""
# traverse all matrix elements
for i in range (M):
for j in range (N):
# we start searching for word in dictionary
# if we found a character which is child
# of Trie root
if pChild.children[char_int(boggle[i][j])]:
# print('h')
string = string + boggle[i][j]
search_word(pChild.children[char_int(boggle[i][j])],
boggle, i, j, visited, string)
string = ""
dictionary = [ "GEEKS" , "FOR" , "QUIZ" , "GEE" ]
# root Node of trie t = Boogle()
# insert all words of dictionary into trie n = len (dictionary)
for i in range (n):
t.insert(dictionary[i])
root = t.root
boggle = [[ 'G' , 'I' , 'Z' ],
[ 'U' , 'E' , 'K' ],
[ 'Q' , 'S' , 'E' ]]
# print(root.children) findWords(boggle, root) # This code is contributed by Yashwant Kumar |
// C# program for Boggle game using System;
public class Boggle {
// Alphabet size
static readonly int SIZE = 26;
static readonly int M = 3;
static readonly int N = 3;
// trie Node
public class TrieNode {
public TrieNode[] Child = new TrieNode[SIZE];
// isLeaf is true if the node represents
// end of a word
public bool leaf;
// constructor
public TrieNode()
{
leaf = false ;
for ( int i = 0; i < SIZE; i++)
Child[i] = null ;
}
}
// If not present, inserts a key into the trie
// If the key is a prefix of trie node, just
// marks leaf node
static void insert(TrieNode root, String Key)
{
int n = Key.Length;
TrieNode pChild = root;
for ( int i = 0; i < n; i++) {
int index = Key[i] - 'A' ;
if (pChild.Child[index] == null )
pChild.Child[index] = new TrieNode();
pChild = pChild.Child[index];
}
// make last node as leaf node
pChild.leaf = true ;
}
// function to check that current location
// (i and j) is in matrix range
static bool isSafe( int i, int j, bool [, ] visited)
{
return (i >= 0 && i < M && j >= 0 && j < N && !visited[i, j]);
}
// A recursive function to print all words present on boggle
static void searchWord(TrieNode root, char [, ] boggle, int i,
int j, bool [, ] visited, String str)
{
// if we found word in trie / dictionary
if (root.leaf == true )
Console.WriteLine(str);
// If both I and j in range and we visited
// that element of matrix first time
if (isSafe(i, j, visited)) {
// make it visited
visited[i, j] = true ;
// traverse all child of current root
for ( int K = 0; K < SIZE; K++) {
if (root.Child[K] != null ) {
// current character
char ch = ( char )(K + 'A' );
// Recursively search reaming character of word
// in trie for all 8 adjacent cells of
// boggle[i, j]
if (isSafe(i + 1, j + 1, visited) && boggle[i + 1, j + 1] == ch)
searchWord(root.Child[K], boggle, i + 1, j + 1,
visited, str + ch);
if (isSafe(i, j + 1, visited) && boggle[i, j + 1] == ch)
searchWord(root.Child[K], boggle, i, j + 1,
visited, str + ch);
if (isSafe(i - 1, j + 1, visited) && boggle[i - 1, j + 1] == ch)
searchWord(root.Child[K], boggle, i - 1, j + 1,
visited, str + ch);
if (isSafe(i + 1, j, visited) && boggle[i + 1, j] == ch)
searchWord(root.Child[K], boggle, i + 1, j,
visited, str + ch);
if (isSafe(i + 1, j - 1, visited) && boggle[i + 1, j - 1] == ch)
searchWord(root.Child[K], boggle, i + 1, j - 1,
visited, str + ch);
if (isSafe(i, j - 1, visited) && boggle[i, j - 1] == ch)
searchWord(root.Child[K], boggle, i, j - 1,
visited, str + ch);
if (isSafe(i - 1, j - 1, visited) && boggle[i - 1, j - 1] == ch)
searchWord(root.Child[K], boggle, i - 1, j - 1,
visited, str + ch);
if (isSafe(i - 1, j, visited) && boggle[i - 1, j] == ch)
searchWord(root.Child[K], boggle, i - 1, j,
visited, str + ch);
}
}
// make current element unvisited
visited[i, j] = false ;
}
}
// Prints all words present in dictionary.
static void findWords( char [, ] boggle, TrieNode root)
{
// Mark all characters as not visited
bool [, ] visited = new bool [M, N];
TrieNode pChild = root;
String str = "" ;
// traverse all matrix elements
for ( int i = 0; i < M; i++) {
for ( int j = 0; j < N; j++) {
// we start searching for word in dictionary
// if we found a character which is child
// of Trie root
if (pChild.Child[(boggle[i, j]) - 'A' ] != null ) {
str = str + boggle[i, j];
searchWord(pChild.Child[(boggle[i, j]) - 'A' ],
boggle, i, j, visited, str);
str = "" ;
}
}
}
}
// Driver program to test above function
public static void Main(String[] args)
{
// Let the given dictionary be following
String[] dictionary = { "GEEKS" , "FOR" , "QUIZ" , "GEE" };
// root Node of trie
TrieNode root = new TrieNode();
// insert all words of dictionary into trie
int n = dictionary.Length;
for ( int i = 0; i < n; i++)
insert(root, dictionary[i]);
char [, ] boggle = { { 'G' , 'I' , 'Z' },
{ 'U' , 'E' , 'K' },
{ 'Q' , 'S' , 'E' } };
findWords(boggle, root);
}
} // This code has been contributed by 29AjayKumar |
<script> // Javascript program for Boggle game // Alphabet size let SIZE = 26; let M = 3; let N = 3; // trie Node
class TrieNode { constructor()
{
this .leaf= false ;
this .Child = new Array(SIZE);
for (let i = 0; i < SIZE; i++)
this .Child[i]= null ;
}
} // If not present, inserts a key into the trie // If the key is a prefix of trie node, just
// marks leaf node
function insert(root,Key)
{ let n = Key.length;
let pChild = root;
for (let i = 0; i < n; i++) {
let index = Key[i].charCodeAt(0) - 'A' .charCodeAt(0);
if (pChild.Child[index] == null )
pChild.Child[index] = new TrieNode();
pChild = pChild.Child[index];
}
// make last node as leaf node
pChild.leaf = true ;
} // function to check that current location // (i and j) is in matrix range
function isSafe(i,j,visited)
{ return (i >= 0 && i < M && j >= 0
&& j < N && !visited[i][j]);
} // A recursive function to print // all words present on boggle
function searchWord(root,boggle,i,j,visited,str)
{ // if we found word in trie / dictionary
if (root.leaf == true )
document.write(str+ " <br>" );
// If both I and j in range and we visited
// that element of matrix first time
if (isSafe(i, j, visited)) {
// make it visited
visited[i][j] = true ;
// traverse all child of current root
for (let K = 0; K < SIZE; K++) {
if (root.Child[K] != null ) {
// current character
let ch = String.fromCharCode(K + 'A' .charCodeAt(0));
// Recursively search reaming character of word
// in trie for all 8 adjacent cells of
// boggle[i][j]
if (isSafe(i + 1, j + 1, visited)
&& boggle[i + 1][j + 1] == ch)
searchWord(root.Child[K], boggle,
i + 1, j + 1,
visited, str + ch);
if (isSafe(i, j + 1, visited)
&& boggle[i][j + 1] == ch)
searchWord(root.Child[K], boggle,
i, j + 1,
visited, str + ch);
if (isSafe(i - 1, j + 1, visited)
&& boggle[i - 1][j + 1] == ch)
searchWord(root.Child[K], boggle,
i - 1, j + 1,
visited, str + ch);
if (isSafe(i + 1, j, visited)
&& boggle[i + 1][j] == ch)
searchWord(root.Child[K], boggle,
i + 1, j,
visited, str + ch);
if (isSafe(i + 1, j - 1, visited)
&& boggle[i + 1][j - 1] == ch)
searchWord(root.Child[K], boggle,
i + 1, j - 1,
visited, str + ch);
if (isSafe(i, j - 1, visited)
&& boggle[i][j - 1] == ch)
searchWord(root.Child[K], boggle,
i, j - 1,
visited, str + ch);
if (isSafe(i - 1, j - 1, visited)
&& boggle[i - 1][j - 1] == ch)
searchWord(root.Child[K], boggle,
i - 1, j - 1,
visited, str + ch);
if (isSafe(i - 1, j, visited)
&& boggle[i - 1][j] == ch)
searchWord(root.Child[K], boggle,
i - 1, j,
visited, str + ch);
}
}
// make current element unvisited
visited[i][j] = false ;
}
} // Prints all words present in dictionary. function findWords(boggle,root)
{ // Mark all characters as not visited
let visited = new Array(M);
for (let i=0;i<M;i++)
{
visited[i]= new Array(N);
for (let j=0;j<N;j++)
{
visited[i][j]= false ;
}
}
let pChild = root;
let str = "" ;
// traverse all matrix elements
for (let i = 0; i < M; i++) {
for (let j = 0; j < N; j++) {
// we start searching for word in dictionary
// if we found a character which is child
// of Trie root
if (pChild.Child[(boggle[i][j]).charCodeAt(0) - 'A' .charCodeAt(0)] != null ) {
str = str + boggle[i][j];
searchWord(pChild.Child[(boggle[i][j]).charCodeAt(0) - 'A' .charCodeAt(0)],
boggle, i, j, visited, str);
str = "" ;
}
}
}
} // Driver program to test above function let dictionary=[ "GEEKS" , "FOR" , "QUIZ" , "GEE" ];
// root Node of trie let root = new TrieNode();
// insert all words of dictionary into trie let n = dictionary.length; for (let i = 0; i < n; i++)
insert(root, dictionary[i]);
let boggle = [[ 'G' , 'I' , 'Z' ],
[ 'U' , 'E' , 'K' ],
[ 'Q' , 'S' , 'E' ]];
findWords(boggle, root); // This code is contributed by rag2127 </script> |
GEE GEEKS QUIZ
Complexity Analysis:
-
Time complexity: O(4^(N^2)).
Even after applying trie the time complexity remains same. For every cell there are 4 directions and there are N^2 cells. So the time complexity is O(4^(N^2)). -
Auxiliary Space: O(N^2).
The maximum length of recursion can be N^2, where N is the side of the matrix. So the space Complexity is O(N^2).
OPTIMIZED APPROACH WITHOUT USING TRIE ( Short and Easy to understand with a better Time and Space complexity):
- First, we create a Set Data Structure and add all word in it to avoid duplicate word.
- Then we make a new array of type String and add those set elements to it.
- We check word by word using a for loop whether that particular word is present in the board and if it returns true , we shall add it our ArrayList<String>.
- While searching for a word in the board,we shall use backtracking so that while coming back,we can alter the board as it was before.
- Lastly we sort the array and print it.
// C++ program for word Boggle #include <bits/stdc++.h> using namespace std;
bool exist( char board[][3], string word, int r, int c);
bool search( char board[][3], string word, int len, int i,
int j, int r, int c);
vector<string> wordBoggle( char board[][3],
vector<string> dictionary)
{ int r = 3;
int c = 3;
vector<string> temp;
set<string> st(dictionary.begin(), dictionary.end());
int n = st.size();
string dict[n];
int id = 0;
for (string s : st)
dict[id++] = s;
for ( int i = 0; i < n; i++) {
if (exist(board, dict[i], r, c))
temp.push_back(dict[i]);
}
return temp;
} bool exist( char board[][3], string word, int r, int c)
{ for ( int i = 0; i < r; i++) {
for ( int j = 0; j < c; j++) {
if (board[i][j] == word[0]
&& search(board, word, 0, i, j, r, c))
return true ;
}
}
return false ;
} bool search( char board[][3], string word, int len, int i,
int j, int r, int c)
{ if (i < 0 || i >= r || j < 0 || j >= c)
return false ;
if (board[i][j] != word[len])
return false ;
if (len == word.length() - 1)
return true ;
char ch = board[i][j];
board[i][j] = '@' ;
bool ans
= search(board, word, len + 1, i - 1, j, r, c)
|| search(board, word, len + 1, i + 1, j, r, c)
|| search(board, word, len + 1, i, j - 1, r, c)
|| search(board, word, len + 1, i, j + 1, r, c)
|| search(board, word, len + 1, i - 1, j + 1, r,
c)
|| search(board, word, len + 1, i - 1, j - 1, r,
c)
|| search(board, word, len + 1, i + 1, j - 1, r,
c)
|| search(board, word, len + 1, i + 1, j + 1, r,
c);
board[i][j] = ch;
return ans;
} int main()
{ vector<string> dictionary
= { "GEEKS" , "FOR" , "QUIZ" , "GEE" };
char boggle[][3] = { { 'G' , 'I' , 'Z' },
{ 'U' , 'E' , 'K' },
{ 'Q' , 'S' , 'E' } };
vector<string> ans = wordBoggle(boggle, dictionary);
if (ans.size() == 0)
cout << "-1" << endl;
else {
sort(ans.begin(), ans.end());
for ( int i = 0; i < ans.size(); i++) {
cout << ans[i] << " " ;
}
cout << endl;
}
return 0;
} // Contributed by adityasha4x71 |
// Java program for word Boggle import java.io.*;
import java.util.*;
public class Boggle {
public static String[] wordBoggle( char board[][],
String[] dictionary)
{
int r = board.length;
int c = board[ 0 ].length;
ArrayList<String> temp = new ArrayList<>();
Set<String> set = new HashSet<>();
for (String i : dictionary)
set.add(i);
int n = set.size();
String dict[] = new String[n];
int id = 0 ;
for (String s : set)
dict[id++] = s;
for ( int i = 0 ; i < dict.length; i++) {
if (exist(board, dict[i], r, c))
temp.add(dict[i]);
}
String[] ans = new String[temp.size()];
int idx = 0 ;
for (String i : temp)
ans[idx++] = i;
return ans;
}
public static boolean exist( char board[][], String word,
int r, int c)
{
for ( int i = 0 ; i < r; i++) {
for ( int j = 0 ; j < c; j++) {
if (board[i][j] == word.charAt( 0 )
&& search(board, word, 0 , i, j, r, c))
return true ;
}
}
return false ;
}
public static boolean search( char board[][],
String word, int len,
int i, int j, int r, int c)
{
if (i < 0 || i >= r || j < 0 || j >= c)
return false ;
if (board[i][j] != word.charAt(len))
return false ;
if (len == word.length() - 1 )
return true ;
char ch = board[i][j];
board[i][j] = '@' ;
boolean ans
= search(board, word, len + 1 , i - 1 , j, r, c)
|| search(board, word, len + 1 , i + 1 , j, r,
c)
|| search(board, word, len + 1 , i, j - 1 , r,
c)
|| search(board, word, len + 1 , i, j + 1 , r,
c)
|| search(board, word, len + 1 , i - 1 , j + 1 ,
r, c)
|| search(board, word, len + 1 , i - 1 , j - 1 ,
r, c)
|| search(board, word, len + 1 , i + 1 , j - 1 ,
r, c)
|| search(board, word, len + 1 , i + 1 , j + 1 ,
r, c);
board[i][j] = ch;
return ans;
}
public static void main(String[] args)
{
String dictionary[]
= { "GEEKS" , "FOR" , "QUIZ" , "GEE" };
char boggle[][] = { { 'G' , 'I' , 'Z' },
{ 'U' , 'E' , 'K' },
{ 'Q' , 'S' , 'E' } };
String ans[] = wordBoggle(boggle, dictionary);
if (ans.length == 0 )
System.out.println( "-1" );
else {
Arrays.sort(ans);
for ( int i = 0 ; i < ans.length; i++) {
System.out.print(ans[i] + " " );
}
System.out.println();
}
}
} // This code is contributed by Raunak Singh |
# Python code addition def exist(board, word, r, c):
for i in range (r):
for j in range (c):
if board[i][j] = = word[ 0 ] and search(board, word, 0 , i, j, r, c):
return True
return False
def search(board, word, length, i, j, r, c):
if i < 0 or i > = r or j < 0 or j > = c:
return False
if board[i][j] ! = word[length]:
return False
if length = = len (word) - 1 :
return True
ch = board[i][j]
board[i][j] = '@'
ans = search(board, word, length + 1 , i - 1 , j, r, c) or \
search(board, word, length + 1 , i + 1 , j, r, c) or \
search(board, word, length + 1 , i, j - 1 , r, c) or \
search(board, word, length + 1 , i, j + 1 , r, c) or \
search(board, word, length + 1 , i - 1 , j + 1 , r, c) or \
search(board, word, length + 1 , i - 1 , j - 1 , r, c) or \
search(board, word, length + 1 , i + 1 , j - 1 , r, c) or \
search(board, word, length + 1 , i + 1 , j + 1 , r, c)
board[i][j] = ch
return ans
def word_boggle(board, dictionary):
r, c = 3 , 3
temp = []
st = set (dictionary)
n = len (st)
dict = []
for s in st:
dict .append(s)
for i in range (n):
if exist(board, dict [i], r, c):
temp.append( dict [i])
return temp
if __name__ = = '__main__' :
dictionary = [ "GEEKS" , "FOR" , "QUIZ" , "GEE" ]
boggle = [[ 'G' , 'I' , 'Z' ],
[ 'U' , 'E' , 'K' ],
[ 'Q' , 'S' , 'E' ]]
ans = word_boggle(boggle, dictionary)
if len (ans) = = 0 :
print ( "-1" )
else :
ans.sort()
print ( " " .join(ans))
# The code is contributed by Nidhi goel. |
using System;
using System.Collections.Generic;
using System.Linq;
public class Boggle {
public static string [] WordBoggle( char [,] board, string [] dictionary) {
int r = board.GetLength(0);
int c = board.GetLength(1);
var temp = new List< string >();
var set = new HashSet< string >(dictionary);
int n = set .Count;
string [] dict = set .ToArray();
for ( int i = 0; i < dict.Length; i++) {
if (Exist(board, dict[i], r, c)) {
temp.Add(dict[i]);
}
}
string [] ans = temp.ToArray();
return ans;
} public static bool Exist( char [,] board, string word, int r, int c) {
for ( int i = 0; i < r; i++) {
for ( int j = 0; j < c; j++) {
if (board[i, j] == word[0] && Search(board, word, 0, i, j, r, c)) {
return true ;
}
}
}
return false ;
} public static bool Search( char [,] board, string word, int len, int i, int j, int r, int c) {
if (i < 0 || i >= r || j < 0 || j >= c) {
return false ;
}
if (board[i, j] != word[len]) {
return false ;
}
if (len == word.Length - 1) {
return true ;
}
char ch = board[i, j];
board[i, j] = '@' ;
bool ans = Search(board, word, len + 1, i - 1, j, r, c) ||
Search(board, word, len + 1, i + 1, j, r, c) ||
Search(board, word, len + 1, i, j - 1, r, c) ||
Search(board, word, len + 1, i, j + 1, r, c) ||
Search(board, word, len + 1, i - 1, j + 1, r, c) ||
Search(board, word, len + 1, i - 1, j - 1, r, c) ||
Search(board, word, len + 1, i + 1, j - 1, r, c) ||
Search(board, word, len + 1, i + 1, j + 1, r, c);
board[i, j] = ch;
return ans;
} public static void Main( string [] args) {
string [] dictionary = { "GEEKS" , "FOR" , "QUIZ" , "GEE" };
char [,] boggle = { { 'G' , 'I' , 'Z' },
{ 'U' , 'E' , 'K' },
{ 'Q' , 'S' , 'E' } };
string [] ans = WordBoggle(boggle, dictionary);
if (ans.Length == 0) {
Console.WriteLine( "-1" );
} else {
Array.Sort(ans);
foreach ( string word in ans) {
Console.Write(word + " " );
}
Console.WriteLine();
}
} } |
// JavaScript program for word Boggle function exist(board, word, r, c) {
for (let i = 0; i < r; i++) {
for (let j = 0; j < c; j++) {
if (board[i][j] === word[0] && search(board, word, 0, i, j, r, c)) {
return true ;
} } } return false ;
} function search(board, word, len, i, j, r, c) {
if (i < 0 || i >= r || j < 0 || j >= c) {
return false ;
} if (board[i][j] !== word[len]) {
return false ;
} if (len === word.length - 1) {
return true ;
} const ch = board[i][j]; board[i][j] = '@' ;
const ans = search(board, word, len + 1, i - 1, j, r, c) || search(board, word, len + 1, i + 1, j, r, c) || search(board, word, len + 1, i, j - 1, r, c) || search(board, word, len + 1, i, j + 1, r, c) || search(board, word, len + 1, i - 1, j + 1, r, c) || search(board, word, len + 1, i - 1, j - 1, r, c) || search(board, word, len + 1, i + 1, j - 1, r, c) || search(board, word, len + 1, i + 1, j + 1, r, c); board[i][j] = ch; return ans;
} function wordBoggle(board, dictionary) {
const r = 3; const c = 3; const temp = []; const st = new Set(dictionary);
const n = st.size; const dict = Array.from(st); for (let i = 0; i < n; i++) {
if (exist(board, dict[i], r, c)) {
temp.push(dict[i]); } } return temp;
} const dictionary = [ "GEEKS" , "FOR" , "QUIZ" , "GEE" ];
const boggle = [ [ "G" , "I" , "Z" ],
[ "U" , "E" , "K" ],
[ "Q" , "S" , "E" ],
]; const ans = wordBoggle(boggle, dictionary); if (ans.length === 0) {
console.log( "-1" );
} else {
ans.sort(); for (let i = 0; i < ans.length; i++) {
console.log(ans[i] + " " );
} console.log( "" );
} // This code is contributed by user_dtewbxkn77n |
GEE GEEKS QUIZ
Time Complexity: O(N*W + R*C^2)
Space Complexity: O(N*W + R*C)