Find longest palindrome formed by removing or shuffling chars from string
Given a string, find the longest palindrome that can be constructed by removing or shuffling characters from the string. Return only one palindrome if there are multiple palindrome strings of longest length.
Examples:
Input: abc
Output: a OR b OR c
Input: aabbcc
Output: abccba OR baccab OR cbaabc OR
any other palindromic string of length 6.
Input: abbaccd
Output: abcdcba OR ...
Input: aba
Output: aba
We can divide any palindromic string into three parts – beg, mid and end. For palindromic string of odd length say 2n + 1, ‘beg’ consists of first n characters of the string, ‘mid’ will consist of only 1 character i.e. (n + 1)th character and ‘end’ will consists of last n characters of the palindromic string. For palindromic string of even length 2n, ‘mid’ will always be empty. It should be noted that ‘end’ will be reverse of ‘beg’ in order for string to be palindrome.
The idea is to use above observation in our solution. As shuffling of characters is allowed, order of characters doesn’t matter in the input string. We first get frequency of each character in the input string. Then all characters having even occurrence (say 2n) in the input string will be part of the output string as we can easily place n characters in ‘beg’ string and the other n characters in the ‘end’ string (by preserving the palindromic order). For characters having odd occurrence (say 2n + 1), we fill ‘mid’ with one of all such characters. and remaining 2n characters are divided in halves and added at beginning and end.
Below is the implementation of above idea
C++
#include <bits/stdc++.h>
using namespace std;
string findLongestPalindrome(string str)
{
int count[256] = { 0 };
for ( int i = 0; i < str.size(); i++)
count[str[i]]++;
string beg = "" , mid = "" , end = "" ;
for ( char ch = 'a' ; ch <= 'z' ; ch++)
{
if (count[ch] & 1)
{
mid = ch;
count[ch--]--;
}
else
{
for ( int i = 0; i < count[ch]/2 ; i++)
beg.push_back(ch);
}
}
end = beg;
reverse(end.begin(), end.end());
return beg + mid + end;
}
int main()
{
string str = "abbaccd" ;
cout << findLongestPalindrome(str);
return 0;
}
|
Java
class GFG {
static String findLongestPalindrome(String str) {
int count[] = new int [ 256 ];
for ( int i = 0 ; i < str.length(); i++) {
count[str.charAt(i)]++;
}
String beg = "" , mid = "" , end = "" ;
for ( char ch = 'a' ; ch <= 'z' ; ch++) {
if (count[ch] % 2 == 1 ) {
mid = String.valueOf(ch);
count[ch--]--;
}
else {
for ( int i = 0 ; i < count[ch] / 2 ; i++) {
beg += ch;
}
}
}
end = beg;
end = reverse(end);
return beg + mid + end;
}
static String reverse(String str) {
String ans = "" ;
char [] try1 = str.toCharArray();
for ( int i = try1.length - 1 ; i >= 0 ; i--) {
ans += try1[i];
}
return ans;
}
public static void main(String[] args) {
String str = "abbaccd" ;
System.out.println(findLongestPalindrome(str));
}
}
|
Python3
def findLongestPalindrome(strr):
count = [ 0 ] * 256
for i in range ( len (strr)):
count[ ord (strr[i])] + = 1
beg = ""
mid = ""
end = ""
ch = ord ( 'a' )
while ch < = ord ( 'z' ):
if (count[ch] & 1 ):
mid = ch
count[ch] - = 1
ch - = 1
else :
for i in range (count[ch] / / 2 ):
beg + = chr (ch)
ch + = 1
end = beg
end = end[:: - 1 ]
return beg + chr (mid) + end
strr = "abbaccd"
print (findLongestPalindrome(strr))
|
C#
using System;
class GFG
{
static String findLongestPalindrome(String str)
{
int []count = new int [256];
for ( int i = 0; i < str.Length; i++)
{
count[str[i]]++;
}
String beg = "" , mid = "" , end = "" ;
for ( char ch = 'a' ; ch <= 'z' ; ch++)
{
if (count[ch] % 2 == 1)
{
mid = String.Join( "" ,ch);
count[ch--]--;
}
else
{
for ( int i = 0; i < count[ch] / 2; i++)
{
beg += ch;
}
}
}
end = beg;
end = reverse(end);
return beg + mid + end;
}
static String reverse(String str)
{
String ans = "" ;
char [] try1 = str.ToCharArray();
for ( int i = try1.Length - 1; i >= 0; i--)
{
ans += try1[i];
}
return ans;
}
public static void Main()
{
String str = "abbaccd" ;
Console.WriteLine(findLongestPalindrome(str));
}
}
|
Javascript
<script>
function findLongestPalindrome(str)
{
let count = new Array(256);
for (let i=0;i<256;i++)
{
count[i]=0;
}
for (let i = 0; i < str.length; i++) {
count[str[i].charCodeAt(0)]++;
}
let beg = "" , mid = "" , end = "" ;
for (let ch = 'a' .charCodeAt(0);
ch <= 'z' .charCodeAt(0); ch++) {
if (count[ch] % 2 == 1) {
mid = String.fromCharCode(ch);
count[ch--]--;
}
else {
for (let i = 0; i < count[ch] / 2; i++)
{
beg += String.fromCharCode(ch);
}
}
}
end = beg;
end = reverse(end);
return beg + mid + end;
}
function reverse(str)
{
let ans = "" ;
let try1 = str.split( "" );
for (let i = try1.length - 1; i >= 0; i--) {
ans += try1[i];
}
return ans;
}
let str = "abbaccd" ;
document.write(findLongestPalindrome(str));
</script>
|
Time complexity of above solution is O(n) where n is length of the string. Since, number of characters in the alphabet is constant, they do not contribute to asymptotic analysis.
Auxiliary space used by the program is M where M is number of ASCII characters.
Last Updated :
04 Jul, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...