给定一个数组nrr [] ,该数组由相等长度M的N个字符串组成,任务是通过串联字符串来创建最长回文。也可以从给定的字符串集中重新排序和丢弃某些字符串。
例子:
Input: N = 3, arr[] = { “tab”, “one”, “bat” }, M = 3
Output: tabbat
Explanation:
On combining “tab” and “bat” from the given set of input strings, the longest palindromic string is formed.
Input: N = 4, arr[] = { “oo”, “ox”, “xo”, “xx” }, M = 2
Output: oxxxxo
观察:让我们假设,我们选择了从给定数组某个k字符串并选择那些ķ字符串之后,我们得到的是一个回文字符串。然后需要对可能的K值进行观察:
- K是偶数:然后对于每个整数x(1 <= x <= K / 2):
Sx = rev(SK - x + 1)
例如,如果构成最长回文的字符串是S 1 =“ tab”,S 2 =“ ab”,S 3 =“ ba”,S 4 =“ bat”。在此,K = 4。因此,S 1 = rev(S 4 ),S 2 = rev(S 3 )。
- K是奇数:除上述观察之外,中间字符串S (K + 1)/ 2是回文。
方法:显然,从上面的观察中,要获得最大的回文率,给定的数组还必须包含字符串的反面。因此,对于每个字符串,我们都会发现是否存在另一个与之相反的字符串。如果存在,则将这对字符串分别添加到左端和右端。如果有一个或多个回文本身的字符串,请选择其中任何一个并将其放在中间。
下面是上述方法的实现:
C++
// C++ program to find the
// Longest palindrome that can be formed
// by concatenating and reordering
// given N strings of equal length
#include
using namespace std;
// Function to print the longest palindrome
void printPalindrome(vector left,
string mid, vector right)
{
// Printing every string in left vector
for (string x : left)
cout << x;
// Printing the palindromic string
// in the middle
cout << mid;
// Printing the reverse of the right vector
// to make the final output palindromic
reverse(right.begin(), right.end());
for (string x : right)
cout << x;
cout << endl;
}
// Function to find and print the
// longest palindrome that can be formed
void findPalindrome(vector& S, int N, int M)
{
set dict;
for (int i = 0; i < M; i++) {
cin >> S[i];
// Inserting each string in the set
dict.insert(S[i]);
}
// Vectors to add the strings
// in the left and right side
vector left, right;
// To add the already present palindrome
// string in the middle of the solution
string mid;
// Iterating through all the given strings
for (int i = 0; i < N; i++) {
string t = S[i];
reverse(t.begin(), t.end());
// If the string is a palindrome
// it is added in the middle
if (t == S[i])
mid = t;
// Checking if the reverse
// of the string is already
// present in the set
else if (dict.find(t) != dict.end()) {
left.push_back(S[i]);
right.push_back(t);
dict.erase(S[i]);
dict.erase(t);
}
}
printPalindrome(left, mid, right);
}
// Driver code
int main()
{
vector S{ "tab", "one", "bat" };
int M = 3;
int N = S.size();
findPalindrome(S, N, M);
}
Java
// Java program to find the
// Longest palindrome that can be formed
// by concatenating and reordering
// given N Strings of equal length
import java.util.*;
class GFG{
// Function to print the longest palindrome
static void printPalindrome(Vector left,
String mid, Vector right)
{
// Printing every String in left vector
for (String x : left)
System.out.print(x);
// Printing the palindromic String
// in the middle
System.out.print(mid);
// Printing the reverse of the right vector
// to make the final output palindromic
Collections.reverse(right);
for (String x : right)
System.out.print(x);
System.out.println();
}
// Function to find and print the
// longest palindrome that can be formed
static void findPalindrome(Vector S, int N, int M)
{
HashSet dict = new HashSet();
for (int i = 0; i < M; i++) {
// Inserting each String in the set
dict.add(S.get(i));
}
// Vectors to add the Strings
// in the left and right side
Vector left = new Vector(), right = new Vector();
// To add the already present palindrome
// String in the middle of the solution
String mid="";
// Iterating through all the given Strings
for (int i = 0; i < N; i++) {
String t = S.get(i);
t = reverse(t);
// If the String is a palindrome
// it is added in the middle
if (t == S.get(i))
mid = t;
// Checking if the reverse
// of the String is already
// present in the set
else if (dict.contains(t)) {
left.add(S.get(i));
right.add(t);
dict.remove(S.get(i));
dict.remove(t);
}
}
printPalindrome(left, mid, right);
}
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 arr[] = { "tab", "one", "bat" };
Vector S = new Vector(Arrays.asList(arr));
int M = 3;
int N = S.size();
findPalindrome(S, N, M);
}
}
// This code contributed by PrinciRaj1992
Python3
# Function to print the longest palindrome
def printPalindrome(left,mid,right):
# Printing every string in left vector
for x in left:
print(x, end="")
# Printing the palindromic string
# in the middle
print(mid, end="")
# Printing the reverse of the right vector
# to make the final output palindromic
right = right[::-1]
for x in right:
print(x, end = "")
print('\n', end = "")
# Function to find and print the
# longest palindrome that can be formed
def findPalindrome(S, N, M):
d = set()
for i in range(M):
# Inserting each string in the set
d.add(S[i])
# Vectors to add the strings
# in the left and right side
left = []
right = []
# To add the already present palindrome
# string in the middle of the solution
mid = ""
# Iterating through all the given strings
for i in range(N):
t = S[i]
t = t[::-1]
# If the string is a palindrome
# it is added in the middle
if (t == S[i]):
mid = t
# Checking if the reverse
# of the string is already
# present in the set
elif (t in d):
left.append(S[i])
right.append(t)
d.remove(S[i])
d.remove(t)
printPalindrome(left, mid, right)
# Driver code
if __name__ == '__main__':
S = ["tab", "one", "bat"]
M = 3
N = len(S)
findPalindrome(S, N, M)
# This code is contributed by Surendra_Gangwar
C#
// C# program to find the
// longest palindrome that can be formed
// by concatenating and reordering
// given N Strings of equal length
using System;
using System.Collections.Generic;
class GFG{
// Function to print the longest palindrome
static void printPalindrome(List left,
String mid, List right)
{
// Printing every String in left vector
foreach (String x in left)
Console.Write(x);
// Printing the palindromic String
// in the middle
Console.Write(mid);
// Printing the reverse of the right vector
// to make the readonly output palindromic
right.Reverse();
foreach (String x in right)
Console.Write(x);
Console.WriteLine();
}
// Function to find and print the
// longest palindrome that can be formed
static void findPalindrome(List S, int N, int M)
{
HashSet dict = new HashSet();
for (int i = 0; i < M; i++) {
// Inserting each String in the set
dict.Add(S[i]);
}
// Lists to add the Strings
// in the left and right side
List left = new List(),
right = new List();
// To add the already present palindrome
// String in the middle of the solution
String mid="";
// Iterating through all the given Strings
for (int i = 0; i < N; i++) {
String t = S[i];
t = reverse(t);
// If the String is a palindrome
// it is added in the middle
if (t == S[i])
mid = t;
// Checking if the reverse
// of the String is already
// present in the set
else if (dict.Contains(t)) {
left.Add(S[i]);
right.Add(t);
dict.Remove(S[i]);
dict.Remove(t);
}
}
printPalindrome(left, mid, right);
}
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 []arr = { "tab", "one", "bat" };
List S = new List(arr);
int M = 3;
int N = S.Count;
findPalindrome(S, N, M);
}
}
// This code is contributed by Princi Singh
tabbat