GeeksforGeeks App
Open App
Browser
Continue

# Maximize value of Palindrome by rearranging characters of a Substring

Given a string S of length N (1 ≤ N ≤ 103) that consists of a digit from ‘0’ to ‘9’, the task is to find the maximum value of palindrome that could be generated by rearranging characters of a substring.

Examples:

Input: S = “91242459”
Output: 42524
Explanation: Rearrange the substring ‘24245’ to form a palindrome. This will give the maximum value of the palindrome.

Input: S = “25242459”
Output: 5429245

The idea is to find the largest substring that we can rearrange to form palindrome. As in a palindrome every character must be present even number of times except for a maximum of 1 element. So XOR of all elements of substring must be 0 or same with the one with odd occurrences. So we can use bitmasking to find the largest valid substring.

After then among all largest valid substrings we would generate the largest palindrome that are possible by rearranging the characters of the valid substring and keep track of the largest generated palindrome.

Follow the steps below to implement the above idea:

• Initialize an array visited[] for storing the mask that has occurred previously
• Iterate over the string:
• Calculate the current mask by toggling the corresponding bit of the current character in the string.
• Check if the mask is zero, which means the occurrence of all characters is even. So, this is a possible way to rearrange character to palindrome
• Maximize the palindrome value.
• Toggle all possible bits one by one
• Check if the new mask is zero, which means the occurrence of all characters is even except that one. So, this is a possible way to rearrange character to palindrome
• Maximize the palindrome value in the result
• Check if this new mask has occurred before
• Maximize the palindrome value
• Check if the current mask is not been visited yet then, mark the current mask visited at index i.
• Return the result.

Below is the implementation of the above approach:

## C++

```#include <bits/stdc++.h>
using namespace std;

// Function to find the maximum possible
// palindromic value
string maxValue(string& s, int i, int j)
{
map<char, int> mp;

for (int k = i; k <= j; k++) {
mp[s[k]]++;
}

string res = "", oddChar = "";

for (auto it = mp.rbegin(); it != mp.rend(); it++) {
if (it->second % 2 != 0) {
oddChar = it->first;
}
else {
res += string(it->second / 2, it->first);
}
}

string reverseRes = res;
reverse(reverseRes.begin(), reverseRes.end());

string a = res + oddChar + reverseRes;
return a;
}

// Function to find the maximum value
// between two given string
string maxOfBoth(string s1, string s2)
{
if (s1.size() > s2.size())
return s1;
else if (s2.size() > s1.size())
return s2;

return ((s1 > s2) ? s1 : s2);
}

// Generate all possible valid palindrome
// and maximize the value among
// all palindrome
string maxPalindrome(string& s)
{
// Initialize an array visited[] for
// storing the mask that has occurred
// previously
vector<int> visited(5555, -1);

int mask = 0, n = s.size();
string result = "0";

// Iterate over the string
for (int i = 0; i < n; i++) {

// Calculate the mask by toggling
// the corresponding bit of current
// character in the string.
mask ^= (1 << (s[i] - '0'));

// Check if mask is zero, means
// occurrence of all character are
// even. So, this is a possible
// way to rearrange character
// to palindrome

// Maximize the palindrome value
result = maxOfBoth(result, maxValue(s, 0, i));
}

// Toggle all possible bit
// one by one
for (int j = 0; j <= 9; j++) {

// Calculate the new Mask by
// toggling the corresponding

// Check if mask is zero,
// means occurrence of all
// character are even except
// one. So, this is a
// possible way to rearrange
// character to palindrome

// Maximize the palindrome
// value in result
result
= maxOfBoth(result, maxValue(s, 0, i));
}

// Check if this new mask has
// occurred before
else if (visited[newMask] != -1) {

// Maximize the palindrome
// value
result = maxOfBoth(
result,
}
}

// Check if the current mask is
// not been visited yet
// then, Mark the current mask
// visited at index i
}
}

// Return the result
return result;
}

// Drive code
int main()
{
string s = "25242459";

// Function call
cout << maxPalindrome(s);

return 0;
}```

## Java

```import java.util.*;

class Main
{

// Function to find the maximum possible
// palindromic value
public static String maxValue(String s, int i, int j)
{
Map<Character, Integer> mp
= new TreeMap<Character, Integer>(
Collections.reverseOrder());

for (int k = i; k <= j; k++) {
if (mp.containsKey(s.charAt(k))) {
mp.put(s.charAt(k),
mp.get(s.charAt(k)) + 1);
}
else {
mp.put(s.charAt(k), 1);
}
}
String res = "", oddChar = "";
for (Map.Entry<Character, Integer> entry :
mp.entrySet()) {
if (entry.getValue() % 2 != 0) {
oddChar
= Character.toString(entry.getKey());
}
else {
res += new String(
new char[entry.getValue() / 2])
.replace("\0",
Character.toString(
entry.getKey()));
}
}
String reverseRes
= new StringBuilder(res).reverse().toString();
return res + oddChar + reverseRes;
}

// Function to find the maximum value
// between two given string
public static String maxOfBoth(String s1, String s2)
{
if (s1.length() > s2.length())
return s1;
else if (s2.length() > s1.length())
return s2;

return ((s1.compareTo(s2) > 0) ? s1 : s2);
}

// Generate all possible valid palindrome
// and maximize the value among
// all palindrome
public static String maxPalindrome(String s)
{

// Initialize an array visited[] for
// storing the mask that has occurred
// previously
int[] visited = new int[5555];
Arrays.fill(visited, -1);

int mask = 0, n = s.length();
String result = "0";

// Iterate over the string
for (int i = 0; i < n; i++)
{

// Calculate the mask by toggling
// the corresponding bit of current
// character in the string.
mask ^= (1 << (s.charAt(i) - '0'));

// Check if mask is zero, means
// occurrence of all character are
// even. So, this is a possible
// way to rearrange character
// to palindrome
{

// Maximize the palindrome value
result
= maxOfBoth(result, maxValue(s, 0, i));
}

// Toggle all possible bit
// one by one
for (int j = 0; j <= 9; j++)
{

// Calculate the new Mask by
// toggling the corresponding

// Check if mask is zero,
// means occurrence of all
// character are even except
// one. So, this is a
// possible way to rearrange
// character to palindrome
{

// Maximize the palindrome
// value in result
result = maxOfBoth(result,
maxValue(s, 0, i));
}

// Check if this new mask has
// occurred before
{

// Maximize the palindrome
// value
result = maxOfBoth(
result,
i));
}
}

// Check if the current mask is
// not been visited yet
// then, Mark the current mask
// visited at index i
}
}

// Return the result
return result;
}

// Driver code
public static void main(String[] args)
{
String s = "25242459";

// Function call
System.out.println(maxPalindrome(s));
}
}

// This code is contributed by Tapesh(tapeshdua420)```

## Python3

```# Function to find the maximum possible
# palindromic value
def maxValue(s, i, j):
mp = {}

for k in range(i, j + 1):
if s[k] not in mp:
mp[s[k]] = 1
else:
mp[s[k]] += 1

res = ""
oddChar = ""
for key in sorted(mp.keys(), reverse=True):
if mp[key] % 2 != 0:
oddChar = key
else:
res += (mp[key] // 2) * key
reverseRes = res[::-1]
a = res + oddChar + reverseRes
return a

# Function to find the maximum value
# between two given string
def maxOfBoth(s1, s2):
if len(s1) > len(s2):
return s1
elif len(s2) > len(s1):
return s2
else:
return s1 if s1 > s2 else s2

# Generate all possible valid palindrome
# and maximize the value among
# all palindrome
def maxPalindrome(s):
# Initialize an array visited[] for
# storing the mask that has occurred
# previously
visited = [-1 for _ in range(5555)]

n = len(s)
result = "0"

# Iterate over the string
for i in range(n):
# Calculate the mask by toggling
# the corresponding bit of current
# character in the string.
mask ^= (1 << (ord(s[i]) - ord('0')))

# Check if mask is zero, means
# occurrence of all character are
# even. So, this is a possible
# way to rearrange character
# to palindrome
# Maximize the palindrome value
result = maxOfBoth(result, maxValue(s, 0, i))

# Toggle all possible bit
# one by one
for j in range(10):
# Calculate the new Mask by
# toggling the corresponding

# Check if mask is zero,
# means occurrence of all
# character are even except
# one. So, this is a
# possible way to rearrange
# character to palindrome
# Maximize the palindrome
# value in result
result = maxOfBoth(result, maxValue(s, 0, i))

# Check if this new mask has
# occurred before
# Maximize the palindrome
# value
result = maxOfBoth(result, maxValue(

# Check if the current mask is
# not been visited yet
# then, Mark the current mask
# visited at index i

# Return the result
return result

# Function call
print(maxPalindrome("25242459"))

# This code is contributed by Tapesh(tapeshdua420)
```

## C#

```using System;
using System.Collections.Generic;
using System.Linq;

class Program {
// Function to find the maximum possible
// palindromic value
static string maxValue(string s, int i, int j)
{
var mp = new SortedDictionary<char, int>();

for (int k = i; k <= j; k++) {
if (mp.ContainsKey(s[k])) {
mp[s[k]] += 1;
}
else {
mp[s[k]] = 1;
}
}

string res = "", oddChar = "";

foreach(var entry in mp.Reverse())
{
if (entry.Value % 2 != 0) {
oddChar = entry.Key.ToString();
}
else {
res += new String(new char[entry.Value / 2])
.Replace("\0",
entry.Key.ToString());
}
}

string reverseRes
= new string(res.Reverse().ToArray());

return res + oddChar + reverseRes;
}

// Function to find the maximum value
// between two given string
static string maxOfBoth(string s1, string s2)
{

if (s1.Length > s2.Length)
return s1;
else if (s2.Length > s1.Length)
return s2;
return ((s1.CompareTo(s2) > 0) ? s1 : s2);
}

// Generate all possible valid palindrome
// and maximize the value among
// all palindrome
static string maxPalindrome(string s)
{
// Initialize an array visited[] for
// storing the mask that has occurred
// previously
int[] visited = new int[5555];

for (int i = 0; i < visited.Length; i++)
visited[i] = -1;

int mask = 0, n = s.Length;
string result = "0";

// Iterate over the string
for (int i = 0; i < n; i++) {
// Calculate the mask by toggling
// the corresponding bit of current
// character in the string.
mask ^= (1 << (s[i] - '0'));

// Check if mask is zero, means
// occurrence of all character are
// even. So, this is a possible
// way to rearrange character
// to palindrome
// Maximize the palindrome value
result
= maxOfBoth(result, maxValue(s, 0, i));

// Toggle all possible bit
// one by one
for (int j = 0; j <= 9; j++) {
// Calculate the new Mask by
// toggling the corresponding

// Check if mask is zero,
// means occurrence of all
// character are even except
// one. So, this is a
// possible way to rearrange
// character to palindrome
// Maximize the palindrome
// value in result
result = maxOfBoth(result,
maxValue(s, 0, i));
// Check if this new mask has
// occurred before
// Maximize the palindrome
// value
result = maxOfBoth(
result,
i));
}
// Check if the current mask is
// not been visited yet
// then, Mark the current mask
// visited at index i
}
// Return the result
return result;
}

// Driver code
static void Main()
{
string s = "25242459";
// Function call
Console.WriteLine(maxPalindrome(s));
}
}
// This code is contributed by Tapesh(tapeshdua420)```

## Javascript

```  // Function to find the maximum possible
// palindromic value
function maxValue(s, i, j) {
var mp = {};

for (var k = i; k <= j; k++) {
if (mp[s[k]]) {
mp[s[k]]++;
} else {
mp[s[k]] = 1;
}
}
var items = Object.keys(mp).map(
(key) => { return [key, mp[key]] });

items.sort(
(first, second) => { return second[0] - first[0] }
);

var res = "", oddChar = "";
for (var it of items) {
if (it[1] % 2 != 0) {
oddChar = it[0];
} else {
res += new Array(it[1] / 2 + 1).join(it[0]);
}
}
var reverseRes = res.split("").reverse().join("");
return res + oddChar + reverseRes;
}

// Function to find the maximum value
// between two given string
function maxOfBoth(s1, s2) {
if (s1.length > s2.length) {
return s1;
} else if (s2.length > s1.length) {
return s2;
} else {
return (s1 > s2 ? s1 : s2);
}
}

// Generate all possible valid palindrome
// and maximize the value among
// all palindrome
function maxPalindrome(s) {
// Initialize an array visited[] for
// storing the mask that has occurred
// previously
var visited = new Array(5555).fill(-1);

var n = s.length;
var result = "0";

// Iterate over the string
for (var i = 0; i < n; i++) {
// Calculate the mask by toggling
// the corresponding bit of current
// character in the string.
mask ^= (1 << (s[i].charCodeAt() - '0'.charCodeAt()));

// Check if mask is zero, means
// occurrence of all character are
// even. So, this is a possible
// way to rearrange character
// to palindrome

// Maximize the palindrome value
result = maxOfBoth(result, maxValue(s, 0, i));
}

// Toggle all possible bit
// one by one
for (var j = 0; j < 10; j++) {
// Calculate the new Mask by
// toggling the corresponding

// Check if mask is zero,
// means occurrence of all
// character are even except
// one. So, this is a
// possible way to rearrange
// character to palindrome
// Maximize the palindrome
// value in result
result = maxOfBoth(result, maxValue(s, 0, i));
}
// Check if this new mask has
// occurred before
else if (visited[newMask] != -1) {
// Maximize the palindrome
// value
result = maxOfBoth(result, maxValue(s, visited[newMask] + 1, i));
}
}
// Check if the current mask is
// not been visited yet
// then, Mark the current mask
// visited at index i
}
}
// Return the result
return result;
}

// Function call
console.log(maxPalindrome("25242459"))

// This code is contributed by Tapesh(tapeshdua420)
```
Output

`5429245`

Time Complexity: O(N2 * log(N))
Auxiliary Space: O(N)

My Personal Notes arrow_drop_up