- Data Structure
- Networking
- RDBMS
- Operating System
- Java
- MS Excel
- iOS
- HTML
- CSS
- Android
- Python
- C Programming
- C++
- C#
- MongoDB
- MySQL
- Javascript
- PHP
- Physics
- Chemistry
- Biology
- Mathematics
- English
- Economics
- Psychology
- Social Studies
- Fashion Studies
- Legal Studies
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
Maximize value of Palindrome by rearranging characters of a Substring
In this problem, we need to find the maximum palindromic string by rearranging the characters of any substring of the given string.
We will use bitmasking to solve the largest palindromic substring. If any substring has bitmasking 0, it contains all characters even a number of times. So, we can generate a palindromic string using the characters of that substring, and we need to find the maximum palindromic string among them.
Problem statement - We have given a string containing the N numeric characters. We need to find the maximum palindromic string by rearranging the characters of any substring of the given string.
Sample Example
Input
alpha = "81343451";
Output
4315134
Explanation - We can take the '1343451' substring and make it palindromic by rearranging its characters.
Input
alpha = "12345";
Output
5
Explanation - The maximum palindromic string that we can generate using any substring is 5.
Input
alpha = "65433456";
Output
"65433456";
Approach 1
In this approach, we will use bitmasking. We will have a binary string of length 10, and each character of the binary string represents the digits from 0 to 9. If any character's value in the binary string is '1', a related digit exists for an odd number of times in the substring.
If the bit mask contains only 1, we can choose a substring to form a palindromic substring by rearranging its character as it contains only one digit with the odd frequency.
So, we will find all such strings having bitmask 0 or containing only one '1', make them palindromic, and take maximum for an answer.
Algorithm
Step 1 - Define the list of size 1025 (210 + 1) to store the mask index and initialize the 'bitMask' with 0. Also, initialize the answer with '0' to store the maximum valid palindromic string.
Step 2 - Start traversing the string of digits.
Step 3 - Left shift 1 by character value, which can be between 0 to 9, and take XOR of its with the 'bitMask' value.
Step 4 - If 'bitMask' is 0, the substring contains all the characters with an even frequency. So, execute the maxValue() function to get the maximum palindromic string by rearranging the characters of the substring.
Step 4.1 - In the maxValue() function, define the 'freq' map to store the frequency of characters of the substring.
Step 4.2 - Initialize the 'temp' and 'odd' with the empty string.
Step 4.3 - Start traversing the map from the end. If the frequency of the character is odd, store the character in the odd. Otherwise, append freq/2 characters to the 'temp' string.
Step 4.4 - Take the reverse of the temp string.
Step 4.5 - Return the resultant string after appending the temp, odd, and reverse strings.
Step 5 - Execute the getMaximumString() function to get a maximum string from the answer and value returned by the maxValue() function.
Step 5.1 - Return the string with maximum length in the getMaximumString() function. If a string of both strings is the same, return the lexicographically the largest string.
Step 5.2 - Store the maximum string in the 'answer'.
Step 6 - We need to toggle all bits individually and get the maximum answer. So, start traversing the 0 to 9 digits.
Step 7 - In the loop, left shift the 1 by digit value, and take its XOR with the 'bitMask' value.
Step 8 - If 'newBitMask' is 0, the substring contains only 1 character with an odd frequency. So, we can rearrange substrings to make palindromic. Store the maximum substring in 'answer'.
Step 9 - If 'newBitMask' already exists in the 'index' array, take a substring from the index[newbitMask] + 1 to p index, make the maximum palindromic string, and store the maximum string in the 'answer' variable.
Step 10 - If 'bitMask' doesn't exist in the 'index' array, update its value with the 'p' index.
Step 11 - Return the 'answer'.
Example
#include <bits/stdc++.h> using namespace std; // Rearrange characters to get the largest string string maxValue(string &str, int start, int end) { map<char, int> freq; // Count frequency of each digit for (int p = start; p <= end; p++) { freq[str[p]]++; } string temp = "", odd = ""; // Traverse map in reverse order for (auto iter = freq.rbegin(); iter != freq.rend(); iter++) { // Take 1 odd number if (iter->second % 2 != 0) { odd = iter->first; } else { temp += string(iter->second / 2, iter->first); } } // Reverse temp string to append it after the odd character string rev = temp; reverse(rev.begin(), rev.end()); // Return the largest palindromic string return temp + odd + rev; } // Get maximum string string getMaximumString(string temp1, string temp2) { if (temp1.size() > temp2.size()) return temp1; if (temp2.size() > temp1.size()) return temp2; if (temp1 > temp2) { return temp1; } return temp2; } string getMaximumPalindrome(string &alpha) { vector<int> index(1025, -1); int bitMask = 0, len = alpha.size(); string answer = "0"; // Iterate over the string for (int p = 0; p < len; p++) { // Toggle the bit corresponding to the digit in the bitMask bitMask ^= (1 << (alpha[p] - '0')); // When bitMask is 0, all characters appear an even number of times if (bitMask == 0) { // Get maximum palindromic string using characters from 0 to p answer = getMaximumString(answer, maxValue(alpha, 0, p)); } // Change all bits and get a maximum answer for (int q = 0; q <= 9; q++) { // Toggle the mask int newbitMask = bitMask; newbitMask ^= (1 << q); // If all characters appear even a number of times if (newbitMask == 0) { answer = getMaximumString(answer, maxValue(alpha, 0, p)); } // If the new mask has already visited else if (index[newbitMask] != -1) { answer = getMaximumString(answer, maxValue(alpha, index[newbitMask] + 1, p)); } } // Updated the visited index of the mask if (index[bitMask] == -1) { index[bitMask] = p; } } return answer; } int main() { string alpha = "81343451"; cout << "The maximum palindromic substring that we can create is " <<getMaximumPalindrome(alpha); return 0; }
Output
The maximum palindromic substring that we can create is 4315134
Time complexity - O(N*N) for traversing the string and making maximum palindromic substring.
Space complexity - O(N) to store characters' frequency in the map and maximum string in the answer.
Bitmasking is a very powerful technique to make any solution efficient. If we solve the problem using the naïve approach, it takes O(N*N) time to find all substrings and O(N) times to rearrange characters of the substring. So, we solved the problem in O(N*N) time complexity instead of O(N3).