Given an array of strings arr[] of the same length, the task is to find the longest palindromic string that can be made using the concatenation of strings in any order.
Examples:
Input: arr[] = {“aba”, “aba”}
Output: abaabaInput: arr[] = {“abc”, “dba”, “kop”, “cba”, “abd”}
Output: abcdbaabdcba
Approach:
- Find all the pairs of strings which are reverse of each other and store them in two different arrays pair1[] and pair2 separately and delete those pairs from the original array.
- Find any palindromic string s1 in the array.
- Join all the strings together of the array pair1[] into s2
- Join all the strings together of the array pair2[] in reverse order into s3
- Concatenate the strings s2 + s1 + s3 together to get longest palindromic string.
Below is the implementation of the above approach.
C++
// C++ implementation to find the longest // palindromic String formed using // concatenation of given strings in any order #include <bits/stdc++.h> using namespace std; // Function to find the longest palindromic // from given array of strings void longestPalindrome(string a[], int n) { string pair1[n]; string pair2[n]; int r = 0; // Loop to find the pair of strings // which are reverse of each other for ( int i = 0; i < n; i++) { string s = a[i]; reverse(s.begin(), s.end()); for ( int j = i + 1; j < n; j++) { if (a[i] != "" && a[j] != "" ) { if (s == a[j]) { pair1[r] = a[i]; pair2[r++] = a[j]; a[i] = "" ; a[j] = "" ; break ; } } } } string s1 = "" ; // Loop to find if any palindromic // string is still left in the array for ( int i = 0; i < n; i++) { string s = a[i]; reverse(a[i].begin(), a[i].end()); if (a[i] != "" ) { if (a[i] == s) { s1 = a[i]; break ; } } } string ans = "" ; // Update the answer with // all strings of pair1 for ( int i = 0; i < r; i++) { ans = ans + pair1[i]; } // Update the answer with // palindromic string s1 if (s1 != "" ) { ans = ans + s1; } // Update the answer with // all strings of pair2 for ( int j = r - 1; j >= 0; j--) { ans = ans + pair2[j]; } cout << ans << endl; } // Driver Code int main() { string a1[2] = { "aba" , "aba" }; int n1 = sizeof (a1) / sizeof (a1[0]); longestPalindrome(a1, n1); string a2[5] = { "abc" , "dba" , "kop" , "abd" , "cba" }; int n2 = sizeof (a2) / sizeof (a2[0]); longestPalindrome(a2, n2); } |
Java
// Java implementation to find the longest // palindromic String formed using // concatenation of given Strings in any order class GFG { // Function to find the longest palindromic // from given array of Strings static void longestPalindrome(String a[], int n) { String []pair1 = new String[n]; String []pair2 = new String[n]; int r = 0 ; // Loop to find the pair of Strings // which are reverse of each other for ( int i = 0 ; i < n; i++) { String s = a[i]; s = reverse(s); for ( int j = i + 1 ; j < n; j++) { if (a[i] != "" && a[j] != "" ) { if (s.equals(a[j])) { pair1[r] = a[i]; pair2[r++] = a[j]; a[i] = "" ; a[j] = "" ; break ; } } } } String s1 = "" ; // Loop to find if any palindromic // String is still left in the array for ( int i = 0 ; i < n; i++) { String s = a[i]; a[i] = reverse(a[i]); if (a[i] != "" ) { if (a[i].equals(s)) { s1 = a[i]; break ; } } } String ans = "" ; // Update the answer with // all Strings of pair1 for ( int i = 0 ; i < r; i++) { ans = ans + pair1[i]; } // Update the answer with // palindromic String s1 if (s1 != "" ) { ans = ans + s1; } // Update the answer with // all Strings of pair2 for ( int j = r - 1 ; j >= 0 ; j--) { ans = ans + pair2[j]; } System.out.print(ans + "\n" ); } static String reverse(String input) { char [] a = input.toCharArray(); int l, r = a.length - 1 ; for (l = 0 ; l < r; l++, r--) { char temp = a[l]; a[l] = a[r]; a[r] = temp; } return String.valueOf(a); } // Driver Code public static void main(String[] args) { String []a1 = { "aba" , "aba" }; int n1 = a1.length; longestPalindrome(a1, n1); String []a2 = { "abc" , "dba" , "kop" , "abd" , "cba" }; int n2 = a2.length; longestPalindrome(a2, n2); } } // This code is contributed by Rajput-Ji |
Python3
# Python3 implementation to find the longest # palindromic String formed using # concatenation of given strings in any order # Function to find the longest palindromic # from given array of strings def longestPalindrome(a, n): pair1 = [ 0 ] * n pair2 = [ 0 ] * n r = 0 # Loop to find the pair of strings # which are reverse of each other for i in range (n): s = a[i] s = s[:: - 1 ] for j in range (i + 1 , n): if (a[i] ! = " " and a[j] != " "): if (s = = a[j]): pair1[r] = a[i] pair2[r] = a[j] r + = 1 a[i] = "" a[j] = "" break s1 = "" # Loop to find if any palindromic # is still left in the array for i in range (n): s = a[i] a[i] = a[i][:: - 1 ] if (a[i] ! = ""): if (a[i] = = s): s1 = a[i] break ans = "" # Update the answer with # all strings of pair1 for i in range (r): ans = ans + pair1[i] # Update the answer with # palindromic s1 if (s1 ! = ""): ans = ans + s1 # Update the answer with # all strings of pair2 for j in range (r - 1 , - 1 , - 1 ): ans = ans + pair2[j] print (ans) # Driver Code a1 = [ "aba" , "aba" ] n1 = len (a1) longestPalindrome(a1, n1) a2 = [ "abc" , "dba" , "kop" , "abd" , "cba" ] n2 = len (a2) longestPalindrome(a2, n2) # This code is contributed by mohit kumar 29 |
C#
// C# implementation to find the longest // palindromic String formed using // concatenation of given Strings in any order using System; class GFG { // Function to find the longest palindromic // from given array of Strings static void longestPalindrome(String []a, int n) { String []pair1 = new String[n]; String []pair2 = new String[n]; int r = 0; // Loop to find the pair of Strings // which are reverse of each other for ( int i = 0; i < n; i++) { String s = a[i]; s = reverse(s); for ( int j = i + 1; j < n; j++) { if (a[i] != "" && a[j] != "" ) { if (s.Equals(a[j])) { pair1[r] = a[i]; pair2[r++] = a[j]; a[i] = "" ; a[j] = "" ; break ; } } } } String s1 = "" ; // Loop to find if any palindromic // String is still left in the array for ( int i = 0; i < n; i++) { String s = a[i]; a[i] = reverse(a[i]); if (a[i] != "" ) { if (a[i].Equals(s)) { s1 = a[i]; break ; } } } String ans = "" ; // Update the answer with // all Strings of pair1 for ( int i = 0; i < r; i++) { ans = ans + pair1[i]; } // Update the answer with // palindromic String s1 if (s1 != "" ) { ans = ans + s1; } // Update the answer with // all Strings of pair2 for ( int j = r - 1; j >= 0; j--) { ans = ans + pair2[j]; } Console.Write(ans + "\n" ); } static String reverse(String input) { char [] a = input.ToCharArray(); int l, r = a.Length - 1; for (l = 0; l < r; l++, r--) { char temp = a[l]; a[l] = a[r]; a[r] = temp; } return String.Join( "" ,a); } // Driver Code public static void Main(String[] args) { String []a1 = { "aba" , "aba" }; int n1 = a1.Length; longestPalindrome(a1, n1); String []a2 = { "abc" , "dba" , "kop" , "abd" , "cba" }; int n2 = a2.Length; longestPalindrome(a2, n2); } } // This code is contributed by 29AjayKumar |
Javascript
<script> // Javascript implementation to find the longest // palindromic String formed using // concatenation of given strings in any order // Function to find the longest palindromic // from given array of strings function longestPalindrome(a, n) { var pair1 = Array(n); var pair2 = Array(n); var r = 0; // Loop to find the pair of strings // which are reverse of each other for ( var i = 0; i < n; i++) { var s = a[i]; s = s.split( '' ).reverse().join( '' ); for ( var j = i + 1; j < n; j++) { if (a[i] != "" && a[j] != "" ) { if (s == a[j]) { pair1[r] = a[i]; pair2[r++] = a[j]; a[i] = "" ; a[j] = "" ; break ; } } } } var s1 = "" ; // Loop to find if any palindromic // string is still left in the array for ( var i = 0; i < n; i++) { var s = a[i]; a[i] = a[i].split( '' ).reverse().join( '' ); if (a[i] != "" ) { if (a[i] == s) { s1 = a[i]; break ; } } } var ans = "" ; // Update the answer with // all strings of pair1 for ( var i = 0; i < r; i++) { ans = ans + pair1[i]; } // Update the answer with // palindromic string s1 if (s1 != "" ) { ans = ans + s1; } // Update the answer with // all strings of pair2 for ( var j = r - 1; j >= 0; j--) { ans = ans + pair2[j]; } document.write(ans + "<br>" ); } // Driver Code var a1 = [ "aba" , "aba" ]; var n1 = a1.length; longestPalindrome(a1, n1); var a2 = [ "abc" , "dba" , "kop" , "abd" , "cba" ]; var n2 = a2.length; longestPalindrome(a2, n2); // This code is contributed by rrrtnx </script> |
abaaba abcdbaabdcba
Time Complexity: O(N2)
Auxiliary Space: O(N)
Method 2
Approach: One point to note down is that basically there are two types of strings. First, the strings which are palindrome let us say pallString and second, the strings that are not palindrome let us say notPallString. We will store pallString in a hashmap pallMap and notPallString in hashmap notPallMap. Now assume we have an array ans[] which stores the final palindromic string inside it. We also have two pointers i and j such that i points to starting index of ans and j points to the last index of ans.
Now we will travel our given array, arr. If we get pallString then we will increase its frequency in pallMap. If we get notPallString then it is an interesting case. We will check if it’s reverse, reverse_notPallString exists in notPallMap or not. If reverse_notPallString exists in the notPallMap in that case notPallString and reverse_notpallString can be part of our ans array. So we will add notPallString at index i and reverse_notPallString at index j . We will also decrease the frequency of reverse_notPallString from our notPallMap. After this, we will increase i and decrease j. If reverse_notpallString does not exist in notPallMap, then we will increase the frequency of notPallString in notPallMap. Similarly, we will travel the whole array. After traveling the whole arr, pallMap will store the strings and their frequency which are palindromes on their own. So we will iterate over the pallMap. Assume we have the string pall_string and its frequency as freq as we are iterating the pallMap. Now while the freq > 1, we will add pall_string at index i and index j respectively, and will decrease the freq by 2. We will also increase i pointer and decrease j pointer. We will also maintain whether we got any odd freq or not because such pall_string does not require any other string to be part of ans array. So such pall can be at the center of our ans array .
After the above steps, our ans array will store the palindromic arrangements of arr.
Algorithm:
1) Maintain an array ans which will sore the palindromic strings. Pointer i will point to the starting of ans and j will point to the ending of ans
1) Iterate the array arr
2) If you got a pallString, then increase its frequency in the pallMap
3) If you got a notPallString, than
3.1) Check if its reverse reverse_notPallString exists in the notPallMap or not
3.2) If the reverse_notPallString exists in notPallMap then add noPallString at index i and reverse_notPallString at index j. Also decrease the frequency of reverse_notPallString from notPallMap. Increase i pointer and decrease j pointer after the addition of the strings in ans .
3.3) If the reverse_notPallString does not exist in notPallMap then increase the frequency of notPallString in notPallMap
4) After traveling the arr, travel the pallMap as it will have palindromic strings pall_string with its frequency as freq
5) Now, while the freq > 1, add pall_string at index i and j. Also, decrease the freq by 2.
6) Note if any freq is odd or not because such pall_string, let us say centre_string can be at the center of our array arr as it is a palindrome and does not require any reverse to contribute to the ans .
7) Travel ans and, and store the valid strings in your result (skipping null values)
Below is the implementation of the above approach.
C++
#include <iostream> #include <string> #include <unordered_map> #include <vector> using namespace std; void solve(string arr[], int n); int main() { string a1[] = { "aba" , "aba" }; int n1 = sizeof (a1) / sizeof (a1[0]); solve(a1, n1); string a2[] = { "abc" , "dba" , "kop" , "abd" , "cba" }; int n2 = sizeof (a2) / sizeof (a2[0]); solve(a2, n2); // abaaba // abdcbaabcdba return 0; } void solve(string arr[], int n) { // array ans[] will store the final palindromic // strings vector<string> ans(n); // pointer i at starting and j at ending index of //ans int i = 0, j = n - 1; // pallMap wil store the palindromic strings unordered_map<string, int > pallMap; // notPallMap will store the not palindromic //strings unordered_map<string, int > notPallMap; for ( int k = 0; k < n; k++) { // String str1 will store the //string of arr string str1 = arr[k]; // freq is the frequency of //pall_String string str2 = string(str1.rbegin(), str1.rend()); if (str1 == str2) { // if the str1 is a palindromic //string than increase its frequency in pallMap pallMap[str1]++; } else { // check if reverse string str2 exist in //notPallMap or not int freq = notPallMap[str2]; // if str2 not exist than increase it's //frequency in notPallMap if (freq == 0) { notPallMap[str1]++; } else { // if str2 //exist in the notPallMap than add str1 at //index i and str2 at index j ans[i] = str1; ans[j] = str2; // increase i //and decrease j after adding in ans i++; j--; // decrease the //frequency of str2 in notPallMap notPallMap[str2]--; } } } // Stirng odd will store the palindromic string with //odd frequency string odd; // travel the hashMap, pallMap for ( auto & kk : pallMap) { // pall_String is the palindromic //string string pall_string = kk.first; // freq is the frequency of //pall_String int freq = kk.second; if (freq % 2 == 1) { while (freq > 1) { ans[i++] = pall_string; ans[j--] = pall_string; freq -= 2; } // if the freq is odd, than store it in //String odd if (odd.empty()) { odd = pall_string; } } else { while (freq > 0) { ans[i++] = pall_string; ans[j--] = pall_string; freq -= 2; } } } // Store the String odd in ans if it is not //null if (!odd.empty()) { ans[i++] = odd; } // String res will hold the final palindromic //string string res; for ( auto & temp : ans) { // if String is not null than add //it in ans if (!temp.empty()) { res += temp; } } cout << res << endl; } string reverse(string input) { int l, r = input.size() - 1; for (l = 0; l < r; l++, r--) { char temp = input[l]; input[l] = input[r]; input[r] = temp; } return input; } |
Java
import java.util.*; import java.io.*; public class GFG { public static void main(String[] args) { String []a1 = { "aba" , "aba" }; int n1 = a1.length; solve(a1, n1); String []a2 = { "abc" , "dba" , "kop" , "abd" , "cba" }; int n2 = a2.length; solve(a2, n2); // abaaba // abdcbaabcdba } static void solve( String[] arr , int n ) { // array ans[] will store the final palindromic strings String ans[] = new String[n] ; // pointer i at starting and j at ending index of ans int i = 0 , j = n- 1 ; // pallMap wil store the palindromic strings HashMap< String , Integer > pallMap = new HashMap<>() ; // notPallMap will store the not palindromic strings HashMap< String , Integer > notPallMap = new HashMap<>() ; for ( int k = 0 ; k < n ; k++) { // String str1 will store the string of arr String str1 = arr[k] ; // String str2 will store the reverse of string str1 String str2 = reverse(str1) ; if (str1.equals(str2)) { // if the str1 is a palindromic string // than increase its frequency in pallMap pallMap.put( str1, pallMap.getOrDefault( pallMap , 0 ) + 1 ) ; } else { // check if reverse string str2 exist in notPallMap or not int freq = notPallMap.getOrDefault( str2 , 0 ) ; // if str2 not exist than increase it's frequency in notPallMap if ( freq == 0 ) { notPallMap.put( str1, notPallMap.getOrDefault( str1 , 0 ) + 1 ) ; } else { // if str2 exist in the notPallMap than // add str1 at index i and str2 at index j ans[i] = str1 ; ans[j] = str2 ; // increase i and decrease j after adding in ans i++;j--; // decrease the frequency of str2 in notPallMap notPallMap.put( str2 , freq - 1 ) ; } } } // Stirng odd will store the palindromic string with odd frequency String odd = null ; // travel the hashMap, pallMap for ( Map.Entry<String , Integer> kk : pallMap.entrySet()) { // pall_String is the palindromic string String pall_string = kk.getKey() ; // freq is the frequency of pall_String int freq = kk.getValue(); if ( freq % 2 == 1 ) { while ( freq > 1 ) { ans[i++] = pall_string ; ans[j--] = pall_string ; freq-= 2 ; } // if the freq is odd, than store it in String odd if ( odd == null ) { odd = pall_string ; } } else { while ( freq > 0 ) { ans[i++] = pall_string ; ans[j--] = pall_string ; freq-= 2 ; } } } // Store the String odd in ans if it is not null if ( odd != null ) ans[i++] = odd ; // String res will hold the final palindromic string String res = "" ; for ( String temp :ans ) { // if String is not null than add it in ans if ( temp != null ) { res += temp ; } } System.out.println(res); } static String reverse(String input) { char [] a = input.toCharArray(); int l, r = a.length - 1 ; for (l = 0 ; l < r; l++, r--) { char temp = a[l]; a[l] = a[r]; a[r] = temp; } return String.valueOf(a); } } |
Python
from collections import defaultdict def solve(arr, n): # array ans[] will store the final palindromic strings ans = [ None ] * n # pointer i at starting and j at ending index of ans i, j = 0 , n - 1 # pallMap wil store the palindromic strings pallMap = defaultdict( int ) # notPallMap will store the not palindromic strings notPallMap = defaultdict( int ) for k in range (n): # String str1 will store the string of arr str1 = arr[k] # String str2 will store the reverse of string str1 str2 = str1[:: - 1 ] if str1 = = str2: # if the str1 is a palindromic string # than increase its frequency in pallMap pallMap[str1] + = 1 else : # check if reverse string str2 exist in notPallMap or not freq = notPallMap.get(str2, 0 ) # if str2 not exist than increase it's frequency in notPallMap if freq = = 0 : notPallMap[str1] + = 1 else : # if str2 exist in the notPallMap than # add str1 at index i and str2 at index j ans[i] = str1 ans[j] = str2 # increase i and decrease j after adding in ans i + = 1 j - = 1 # decrease the frequency of str2 in notPallMap notPallMap[str2] - = 1 # Stirng odd will store the palindromic string with odd frequency odd = None # travel the hashMap, pallMap for pall_string, freq in pallMap.items(): # pall_String is the palindromic string # freq is the frequency of pall_String if freq % 2 = = 1 : while freq > 1 : ans[i] = pall_string ans[j] = pall_string i + = 1 j - = 1 freq - = 2 # if the freq is odd, than store it in String odd if odd is None : odd = pall_string else : while freq > 0 : ans[i] = pall_string ans[j] = pall_string i + = 1 j - = 1 freq - = 2 # Store the String odd in ans if it is not null if odd is not None : ans[i] = odd # String res will hold the final palindromic string res = ''.join(x for x in ans if x is not None ) print (res) if __name__ = = '__main__' : a1 = [ "aba" , "aba" ] n1 = len (a1) solve(a1, n1) a2 = [ "abc" , "dba" , "kop" , "abd" , "cba" ] n2 = len (a2) solve(a2, n2) |
C#
using System; using System.Collections.Generic; namespace GFG { class Program { static void Main( string [] args) { // Input arrays string [] a1 = { "aba" , "aba" }; int n1 = a1.Length; Solve(a1, n1); string [] a2 = { "abc" , "dba" , "kop" , "abd" , "cba" }; int n2 = a2.Length; Solve(a2, n2); } static void Solve( string [] arr, int n) { // Array to store final palindromic strings string [] ans = new string [n]; int i = 0, j = n - 1; // Dictionary to store palindromic strings and their frequencies Dictionary< string , int > pallMap = new Dictionary< string , int >(); // Dictionary to store non-palindromic strings and their frequencies Dictionary< string , int > notPallMap = new Dictionary< string , int >(); for ( int k = 0; k < n; k++) { string str1 = arr[k]; string str2 = Reverse(str1); if (str1.Equals(str2)) { // Increase the frequency of palindromic string in pallMap pallMap[str1] = pallMap.GetValueOrDefault(str1) + 1; } else { int freq = notPallMap.GetValueOrDefault(str2); if (freq == 0) { // Increase the frequency of non-palindromic string in notPallMap notPallMap[str1] = notPallMap.GetValueOrDefault(str1) + 1; } else { // Store strings in ans and adjust indices ans[i] = str1; ans[j] = str2; i++; j--; // Decrease the frequency of str2 in notPallMap notPallMap[str2] = freq - 1; } } } string odd = null ; foreach (KeyValuePair< string , int > kvp in pallMap) { string pallString = kvp.Key; int freq = kvp.Value; if (freq % 2 == 1) { while (freq > 1) { ans[i++] = pallString; ans[j--] = pallString; freq -= 2; } if (odd == null ) { // Store the odd frequency palindromic string odd = pallString; } } else { while (freq > 0) { ans[i++] = pallString; ans[j--] = pallString; freq -= 2; } } } if (odd != null ) { // Store the odd frequency palindromic string in ans ans[i++] = odd; } // Concatenate the strings in ans to form the result string res = string .Join( "" , ans); Console.WriteLine(res); } static string Reverse( string input) { // Reverse the characters in the string char [] a = input.ToCharArray(); int l, r = a.Length - 1; for (l = 0; l < r; l++, r--) { char temp = a[l]; a[l] = a[r]; a[r] = temp; } return new string (a); } } } // This code is contributed by Dwaipayan Bandyopadhyay |
Javascript
// This function takes an array of strings arr and the length of the array n as input function solve(arr, n) { // Initialize an array of length n with null values let ans = new Array(n).fill( null ); // Initialize i and j variables let i = 0, j = n - 1; // Initialize two maps for storing palindromic and non-palindromic strings let pallMap = new Map(); let notPallMap = new Map(); // Initialize an odd variable to null let odd = null ; // Loop through the input array arr for (let k = 0; k < n; k++) { // Get the string at index k let str1 = arr[k]; // Reverse the string let str2 = str1.split( '' ).reverse().join( '' ); // If the string is palindromic, store it in the `pallMap` if (str1 === str2) { if (pallMap.has(str1)) { pallMap.set(str1, pallMap.get(str1) + 1); } else { pallMap.set(str1, 1); } } else { // If the string is not palindromic, store it in the `notPallMap` if (notPallMap.has(str2)) { let freq = notPallMap.get(str2); if (freq > 0) { ans[i] = str1; ans[j] = str2; i++; j--; notPallMap.set(str2, freq - 1); } else { notPallMap.set(str1, notPallMap.get(str1) + 1); } } else { notPallMap.set(str1, 1); } } } // Loop through the palindromic strings stored in the pallMap for (let [pall_string, freq] of pallMap.entries()) { // If the frequency of the palindromic string is odd, store it in the odd variable and add the string to the ans array if (freq % 2 === 1) { while (freq > 1) { ans[i] = pall_string; ans[j] = pall_string; i++; j--; freq -= 2; } if (odd === null ) { odd = pall_string; } } else { // If the frequency of the palindromic string is even, add the string to the ans array while (freq > 0) { ans[i] = pall_string; ans[j] = pall_string; i++; j--; freq -= 2; } } } // If there is a palindromic string with an odd frequency, add it to the middle of the ans array if (odd !== null ) { ans[i] = odd; } // Remove all null values from the ans array and join the remaining values into a single string let res = ans.filter(x => x !== null ).join( '' ); // Print the resulting string console.log(res); } // Example usage of the solve function with two different input arrays let a1 = [ "aba" , "aba" ]; let n1 = a1.length; solve(a1, n1); let a2 = [ "abc" , "dba" , "kop" , "abd" , "cba" ]; let n2 = a2.length; solve(a2, n2); |
abaaba abdcbaabcdba
Time Complexity : O(n)
Auxiliary Space : O(n)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!