Find all concatenations of words in Array
Last Updated :
30 Nov, 2023
Given an array of strings arr[] (1 <= |arr[i]| <= 20) of size N (1 <= N <= 104), the task is to find all strings from the given array that are formed by the concatenation of strings in the same given array.
Examples:
Input: arr[]= { “geek”, “geeks”, “for”, “geeksforgeeks”, “g”, “f”, “g”, “gfg” };
Output: “geeksforgeeks”
Input: arr[] = {“g”, “gforg”, “for”}
Output: {“gforg”}
Naive Approach: The basic way to solve the problem is as follows:
Generate all possible concatation of strings and check if it exists in given array or not. As there are two options for each string of array that wheather we concatenate it or not. Finally, after exploring all such options we’re able to generate all possible concatenations.
Complexity Analysis:
- Time Complexity: 2n
- Auxiliary Space: n
Find all concatenations of words in an array using Hashmap and Recursion:
The idea is to use a map to keep track of word occurrences. For each string extract its prefix, suffix and Check if both the prefix and suffix are in the map (can be concatenated) or Check if the prefix is in the map and recursively check the suffix
Step-by-step approach:
- Store each word in the map for checking the string is present in given array string or not.
- Create an array of string result to store the resulting concatenated strings
- Iterate through the strings and check if they can be concatenated
- Create a Helper function isConcat() to determine if a word can be concatenated
- Check if both the prefix and suffix of string are in the map (can be concatenated), return true
- Check if the prefix is in the map and recursively check the suffix, return true
- If no valid concatenation is found, return false
- Count the frequency of each word and store it in the map
Below is the implemenation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
unordered_map<string, int > unmap;
bool isConcat( int i, string& word)
{
string prefix = "";
for ( int k = 0; k < word.size() - 1; k++) {
prefix += word[k];
string suffix = word.substr(k + 1);
if (unmap.find(prefix) != unmap.end()
&& unmap.find(suffix) != unmap.end()) {
return true ;
}
else if (unmap.find(prefix) != unmap.end()
&& isConcat(i + 1, suffix)) {
return true ;
}
}
return false ;
}
int main()
{
vector<string> arr
= { "geek", "geeks", " for ", "geeksforgeeks",
"g", "f", "g", "gfg" };
vector<string> result;
for ( auto s : arr)
unmap[s]++;
for ( auto s : arr) {
if (isConcat(0, s))
result.push_back(s);
}
for ( auto s : result)
cout << s << " ";
}
|
Java
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ConcatenatedWords {
static Map<String, Integer> wordFrequency
= new HashMap<>();
public static boolean isConcat(String word)
{
StringBuilder prefix = new StringBuilder();
for ( int k = 0 ; k < word.length() - 1 ; k++) {
prefix.append(word.charAt(k));
String suffix = word.substring(k + 1 );
if (wordFrequency.containsKey(prefix.toString())
&& wordFrequency.containsKey(suffix)) {
return true ;
}
if (wordFrequency.containsKey(prefix.toString())
&& isConcat(suffix)) {
return true ;
}
}
return false ;
}
public static void main(String[] args)
{
List<String> words = new ArrayList<>();
words.add( "geek" );
words.add( "geeks" );
words.add( "for" );
words.add( "geeksforgeeks" );
words.add( "g" );
words.add( "f" );
words.add( "g" );
words.add( "gfg" );
List<String> result = new ArrayList<>();
for (String word : words) {
wordFrequency.put(
word,
wordFrequency.getOrDefault(word, 0 ) + 1 );
}
for (String word : words) {
if (isConcat(word)) {
result.add(word);
}
}
for (String word : result) {
System.out.print(word + " " );
}
}
}
|
Python
unmap = {}
def is_concat(i, word):
global unmap
prefix = ""
for k in range ( len (word) - 1 ):
prefix + = word[k]
suffix = word[k + 1 :]
if prefix in unmap and suffix in unmap:
return True
elif prefix in unmap and is_concat(i + 1 , suffix):
return True
return False
if __name__ = = "__main__" :
arr = [ "geek" , "geeks" , "for" , "geeksforgeeks" , "g" , "f" , "g" , "gfg" ]
result = []
for s in arr:
if s in unmap:
unmap[s] + = 1
else :
unmap[s] = 1
for s in arr:
if is_concat( 0 , s):
result.append(s)
print ( " " .join(result))
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static Dictionary< string , int > unmap = new Dictionary< string , int >();
static bool IsConcat( int i, string word)
{
string prefix = "" ;
for ( int k = 0; k < word.Length - 1; k++)
{
prefix += word[k];
string suffix = word.Substring(k + 1);
if (unmap.ContainsKey(prefix) && unmap.ContainsKey(suffix))
{
return true ;
}
else if (unmap.ContainsKey(prefix) && IsConcat(i + 1, suffix))
{
return true ;
}
}
return false ;
}
static void Main()
{
string [] arr = { "geek" , "geeks" , "for" , "geeksforgeeks" , "g" , "f" , "g" , "gfg" };
List< string > result = new List< string >();
foreach ( string s in arr)
{
if (unmap.ContainsKey(s))
{
unmap[s]++;
}
else
{
unmap[s] = 1;
}
}
foreach ( string s in arr)
{
if (IsConcat(0, s))
{
result.Add(s);
}
}
Console.WriteLine( string .Join( " " , result));
}
}
|
Javascript
let unmap = {};
function isConcat(i, word) {
let prefix = "" ;
for (let k = 0; k < word.length - 1; k++) {
prefix += word[k];
let suffix = word.substring(k + 1);
if (unmap.hasOwnProperty(prefix) && unmap.hasOwnProperty(suffix)) {
return true ;
}
else if (unmap.hasOwnProperty(prefix) && isConcat(i + 1, suffix)) {
return true ;
}
}
return false ;
}
let arr = [ "geek" , "geeks" , "for" , "geeksforgeeks" , "g" , "f" , "g" , "gfg" ];
let result = [];
arr.forEach(s => {
unmap[s] = (unmap[s] || 0) + 1;
});
arr.forEach(s => {
if (isConcat(0, s)) {
result.push(s);
}
});
console.log(result.join( " " ));
|
Time Complexity: O(N * L^2), where N is the number of words and L is the maximum word length.
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...