Print all valid words that are possible using Characters of Array
Last Updated :
02 Mar, 2023
Given a dictionary and a character array, print all valid words that are possible using characters from the array.
Examples:
Input : Dict - {"go","bat","me","eat","goal",
"boy", "run"}
arr[] = {'e','o','b', 'a','m','g', 'l'}
Output : go, me, goal.
Asked In : Microsoft Interview
The idea is to use Trie data structure to store dictionary, then search words in Trie using characters of given array.
- Create an empty Trie and insert all words of given dictionary into the Trie.
- After that, we have pick only those characters in ‘Arr[]’ which are a child of the root of Trie.
- To quickly find whether a character is present in array or not, we create a hash of character arrays.
Below is the implementation of above idea
C++
// C++ program to print all valid words that
// are possible using character of array
#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')
//converts current integer into character
#define int_to_char(c) ((char)c + (char)'a')
// Alphabet size
#define SIZE (26)
// 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 key into trie
// If the key is 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;
}
// A recursive function to print all possible valid
// words present in array
void searchWord(TrieNode *root, bool Hash[], string str)
{
// if we found word in trie / dictionary
if (root->leaf == true)
cout << str << endl ;
// traverse all child's of current root
for (int K =0; K < SIZE; K++)
{
if (Hash[K] == true && root->Child[K] != NULL )
{
// add current character
char c = int_to_char(K);
// Recursively search reaming character of word
// in trie
searchWord(root->Child[K], Hash, str + c);
}
}
}
// Prints all words present in dictionary.
void PrintAllWords(char Arr[], TrieNode *root, int n)
{
// create a 'has' array that will store all present
// character in Arr[]
bool Hash[SIZE];
for (int i = 0 ; i < n; i++)
Hash[char_int(Arr[i])] = true;
// temporary node
TrieNode *pChild = root ;
// string to hold output words
string str = "";
// Traverse all matrix elements. There are only 26
// character possible in char array
for (int i = 0 ; i < SIZE ; i++)
{
// we start searching for word in dictionary
// if we found a character which is child
// of Trie root
if (Hash[i] == true && pChild->Child[i] )
{
str = str+(char)int_to_char(i);
searchWord(pChild->Child[i], Hash, str);
str = "";
}
}
}
//Driver program to test above function
int main()
{
// Let the given dictionary be following
char Dict[][20] = {"go", "bat", "me", "eat",
"goal", "boy", "run"} ;
// Root Node of Trie
TrieNode *root = getNode();
// insert all words of dictionary into trie
int n = sizeof(Dict)/sizeof(Dict[0]);
for (int i=0; i<n; i++)
insert(root, Dict[i]);
char arr[] = {'e', 'o', 'b', 'a', 'm', 'g', 'l'} ;
int N = sizeof(arr)/sizeof(arr[0]);
PrintAllWords(arr, root, N);
return 0;
}
Java
// Java program to print all valid words that
// are possible using character of array
public class SearchDict_charArray {
// Alphabet size
static final int SIZE = 26;
// 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 key into trie
// If the key is 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;
}
// A recursive function to print all possible valid
// words present in array
static void searchWord(TrieNode root, boolean Hash[],
String str)
{
// if we found word in trie / dictionary
if (root.leaf == true)
System.out.println(str);
// traverse all child's of current root
for (int K =0; K < SIZE; K++)
{
if (Hash[K] == true && root.Child[K] != null )
{
// add current character
char c = (char) (K + 'a');
// Recursively search reaming character
// of word in trie
searchWord(root.Child[K], Hash, str + c);
}
}
}
// Prints all words present in dictionary.
static void PrintAllWords(char Arr[], TrieNode root,
int n)
{
// create a 'has' array that will store all
// present character in Arr[]
boolean[] Hash = new boolean[SIZE];
for (int i = 0 ; i < n; i++)
Hash[Arr[i] - 'a'] = true;
// temporary node
TrieNode pChild = root ;
// string to hold output words
String str = "";
// Traverse all matrix elements. There are only
// 26 character possible in char array
for (int i = 0 ; i < SIZE ; i++)
{
// we start searching for word in dictionary
// if we found a character which is child
// of Trie root
if (Hash[i] == true && pChild.Child[i] != null )
{
str = str+(char)(i + 'a');
searchWord(pChild.Child[i], Hash, str);
str = "";
}
}
}
//Driver program to test above function
public static void main(String args[])
{
// Let the given dictionary be following
String Dict[] = {"go", "bat", "me", "eat",
"goal", "boy", "run"} ;
// Root Node of Trie
TrieNode root = new TrieNode();
// insert all words of dictionary into trie
int n = Dict.length;
for (int i=0; i<n; i++)
insert(root, Dict[i]);
char arr[] = {'e', 'o', 'b', 'a', 'm', 'g', 'l'} ;
int N = arr.length;
PrintAllWords(arr, root, N);
}
}
// This code is contributed by Sumit Ghosh
Python3
# Python program to print all valid words that
# are possible using character of array
# Alphabet size
SIZE = 26
# trie Node
class TrieNode:
def __init__(self):
self.child = [None] * SIZE
# isLeaf is true if the node represents
# end of a word
self.leaf = False
# Converts key current character into index
# use only 'a' through 'z'
def char_int(c):
return ord(c) - ord('a')
# converts current integer into character
def int_to_char(c):
return chr(c + ord('a'))
# Returns new trie node (initialized to NULLs)
def get_node():
new_node = TrieNode()
return new_node
# If not present, inserts key into trie
# If the key is prefix of trie node, just
# marks leaf node
def insert(root, key):
n = len(key)
p_child = root
for i in range(n):
index = char_int(key[i])
if not p_child.child[index]:
p_child.child[index] = get_node()
p_child = p_child.child[index]
# make last node as leaf node
p_child.leaf = True
# A recursive function to print all possible valid
# words present in array
def searchWord(root, hash, string):
# if we found word in trie / dictionary
if root.leaf:
print(string)
# traverse all child's of current root
for k in range(SIZE):
if hash[k] and root.child[k]:
# add current character
c = int_to_char(k)
# Recursively search reaming character of word
# in trie
searchWord(root.child[k], hash, string + c)
# Prints all words present in dictionary.
def print_all_words(arr, root, n):
# create a 'has' array that will store all present
# character in Arr[]
hash = [False] * SIZE
for i in range(n):
hash[char_int(arr[i])] = True
# temporary node
p_child = root
# string to hold output words
string = ""
# Traverse all matrix elements. There are only 26
# character possible in char array
for i in range(SIZE):
# we start searching for word in dictionary
# if we found a character which is child
# of Trie root
if hash[i] and p_child.child[i]:
string = string + int_to_char(i)
searchWord(p_child.child[i], hash, string)
string = ""
# Driver program to test above function
if __name__ == '__main__':
# Let the given dictionary be following
dict = ["go", "bat", "me", "eat", "goal", "boy", "run"]
# Root Node of Trie
root = get_node()
# insert all words of dictionary into trie
n = len(dict)
for i in range(n):
insert(root, dict[i])
arr = ['e', 'o', 'b', 'a', 'm', 'g', 'l']
n = len(arr)
print_all_words(arr, root, n)
# This code is contributed by Aman Kumar.
C#
// C# program to print all valid words that
// are possible using character of array
using System;
public class SearchDict_charArray
{
// Alphabet size
static readonly int SIZE = 26;
// trie Node
public class TrieNode
{
public TrieNode[] Child = new TrieNode[SIZE];
// isLeaf is true if the node represents
// end of a word
public Boolean leaf;
// Constructor
public TrieNode()
{
leaf = false;
for (int i =0 ; i< SIZE ; i++)
Child[i] = null;
}
}
// If not present, inserts key into trie
// If the key is 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;
}
// A recursive function to print all possible valid
// words present in array
static void searchWord(TrieNode root, Boolean []Hash,
String str)
{
// if we found word in trie / dictionary
if (root.leaf == true)
Console.WriteLine(str);
// traverse all child's of current root
for (int K = 0; K < SIZE; K++)
{
if (Hash[K] == true && root.Child[K] != null )
{
// add current character
char c = (char) (K + 'a');
// Recursively search reaming character
// of word in trie
searchWord(root.Child[K], Hash, str + c);
}
}
}
// Prints all words present in dictionary.
static void PrintAllWords(char []Arr, TrieNode root,
int n)
{
// create a 'has' array that will store all
// present character in Arr[]
Boolean[] Hash = new Boolean[SIZE];
for (int i = 0 ; i < n; i++)
Hash[Arr[i] - 'a'] = true;
// temporary node
TrieNode pChild = root ;
// string to hold output words
String str = "";
// Traverse all matrix elements. There are only
// 26 character possible in char array
for (int i = 0 ; i < SIZE ; i++)
{
// we start searching for word in dictionary
// if we found a character which is child
// of Trie root
if (Hash[i] == true && pChild.Child[i] != null )
{
str = str+(char)(i + 'a');
searchWord(pChild.Child[i], Hash, str);
str = "";
}
}
}
// Driver code
public static void Main(String []args)
{
// Let the given dictionary be following
String []Dict = {"go", "bat", "me", "eat",
"goal", "boy", "run"} ;
// Root Node of Trie
TrieNode root = new TrieNode();
// insert all words of dictionary into trie
int n = Dict.Length;
for (int i = 0; i < n; i++)
insert(root, Dict[i]);
char []arr = {'e', 'o', 'b', 'a', 'm', 'g', 'l'} ;
int N = arr.Length;
PrintAllWords(arr, root, N);
}
}
/* This code is contributed by PrinciRaj1992 */
JavaScript
<script>
// JavaScript program to print all valid words that
// are possible using character of array
// Converts key current character into index
// use only 'a' through 'z'
function char_int(c) {
return c.charCodeAt(0) - "a".charCodeAt(0);
}
//converts current integer into character
function int_to_char(c) {
return String.fromCharCode(c + "a".charCodeAt(0));
}
// Alphabet size
const SIZE = 26;
// Trie Node
class TrieNode {
constructor() {
this.Child = new Array(SIZE);
// isLeaf is true if the node represents
// end of a word
this.leaf = false;
}
}
// Returns new trie node (initialized to NULLs)
function getNode() {
const newNode = new TrieNode();
newNode.leaf = false;
for (let i = 0; i < SIZE; i++) {
newNode.Child[i] = null;
}
return newNode;
}
// If not present, inserts key into trie
// If the key is prefix of trie node, just
// marks leaf node
function insert(root, Key) {
const n = Key.length;
let pChild = root;
for (let i = 0; i < n; i++) {
const 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;
}
// A recursive function to print all possible valid
// words present in array
function searchWord(root, Hash, str) {
// if we found word in trie / dictionary
if (root.leaf == true) {
document.write(str+"<br>");
}
// traverse all child's of current root
for (let K = 0; K < SIZE; K++) {
if (Hash[K] == true && root.Child[K] != null) {
// add current character
const c = int_to_char(K);
// Recursively search remaining character of word
// in trie
searchWord(root.Child[K], Hash, str + c);
}
}
}
// Prints all words present in dictionary.
function PrintAllWords(Arr, root, n) {
// create a 'has' array that will store all present
// character in Arr[]
const Hash = new Array(SIZE).fill(false);
for (let i = 0; i < n; i++) {
Hash[char_int(Arr[i])] = true;
}
// temporary node
let pChild = root;
// string to hold output words
let str = "";
// Traverse all matrix elements. There are only 26
// character possible in char array
for (let i = 0; i < SIZE; i++) {
// we start searching for word in dictionary
// if we found a character which is child
// of Trie root
if (Hash[i] == true && pChild.Child[i]) {
str += int_to_char(i);
searchWord(pChild.Child[i], Hash, str);
str = "";
}
}
}
//Driver program to test above function
// Let the given dictionary be following
const Dict = ["go", "bat", "me", "eat", "goal", "boy", "run"];
// Root Node of Trie
const root = getNode();
// insert all words of dictionary into trie
const n = Dict.length;
for (let i = 0; i < n; i++) {
insert(root, Dict[i]);
}
const arr = ["e", "o", "b", "a", "m", "g", "l"];
const N = arr.length;
PrintAllWords(arr, root, N);
// This code is contributed by Utkarsh Kumar
</script>
Outputbat
boy
eat
go
goal
me
run
Time Complexity: O(SIZE^L * N) where L is the length of the longest word in the dictionary and N is the length of the input array.
Auxiliary Space: O(SIZE^L)
Similar Reads
DSA Tutorial - Learn Data Structures and Algorithms DSA (Data Structures and Algorithms) is the study of organizing data efficiently using data structures like arrays, stacks, and trees, paired with step-by-step procedures (or algorithms) to solve problems effectively. Data structures manage how data is stored and accessed, while algorithms focus on
7 min read
Data Structures Tutorial Data structures are the fundamental building blocks of computer programming. They define how data is organized, stored, and manipulated within a program. Understanding data structures is very important for developing efficient and effective algorithms. What is Data Structure?A data structure is a st
2 min read
Merge Sort - Data Structure and Algorithms Tutorials Merge sort is a popular sorting algorithm known for its efficiency and stability. It follows the divide-and-conquer approach. It works by recursively dividing the input array into two halves, recursively sorting the two halves and finally merging them back together to obtain the sorted array. Merge
12 min read
Quick Sort QuickSort is a sorting algorithm based on the Divide and Conquer that picks an element as a pivot and partitions the given array around the picked pivot by placing the pivot in its correct position in the sorted array. It works on the principle of divide and conquer, breaking down the problem into s
12 min read
Bubble Sort Algorithm Bubble Sort is the simplest sorting algorithm that works by repeatedly swapping the adjacent elements if they are in the wrong order. This algorithm is not suitable for large data sets as its average and worst-case time complexity are quite high.We sort the array using multiple passes. After the fir
8 min read
Binary Search Algorithm - Iterative and Recursive Implementation Binary Search Algorithm is a searching algorithm used in a sorted array by repeatedly dividing the search interval in half. The idea of binary search is to use the information that the array is sorted and reduce the time complexity to O(log N). Binary Search AlgorithmConditions to apply Binary Searc
15 min read
Breadth First Search or BFS for a Graph Given a undirected graph represented by an adjacency list adj, where each adj[i] represents the list of vertices connected to vertex i. Perform a Breadth First Search (BFS) traversal starting from vertex 0, visiting vertices from left to right according to the adjacency list, and return a list conta
15+ min read
Linked List Data Structure A linked list is a fundamental data structure in computer science. It mainly allows efficient insertion and deletion operations compared to arrays. Like arrays, it is also used to implement other data structures like stack, queue and deque. Hereâs the comparison of Linked List vs Arrays Linked List:
2 min read
Insertion Sort Algorithm Insertion sort is a simple sorting algorithm that works by iteratively inserting each element of an unsorted list into its correct position in a sorted portion of the list. It is like sorting playing cards in your hands. You split the cards into two groups: the sorted cards and the unsorted cards. T
9 min read
Sorting Algorithms A Sorting Algorithm is used to rearrange a given array or list of elements in an order. For example, a given array [10, 20, 5, 2] becomes [2, 5, 10, 20] after sorting in increasing order and becomes [20, 10, 5, 2] after sorting in decreasing order. There exist different sorting algorithms for differ
3 min read