Make a lexicographically smallest palindrome with minimal changes

Given a string S. Print the lexicographically smallest string possible. You can make minimal changes to the characters in the string and you can permute the string.

Examples:

Input : S = "aabc"
Output : "abba"

Input : S = "äabcd"
Output : "abcba"

Explanation 1:Change the last index “c” to “b”, it becomes “aabb”. Then rearrange the string, it becomes “abba”. This is the lexicographically smallest string.
Explanation 2: change “d” to “b” => “aabcb” => “abcba”.

Recommended: Please try your approach on {IDE} first, before moving on to the solution.

Approach:
cnt[a] be the no.of occurences of the character a. Consider odd values of cnt[a], then a palindrome can not contain more than one character a with cnt[a]. Denote characters with odd count cnt[] as follows a1, a2….ak(in alphabetical order). Replace any of the symbols ak with a1 and ak-1 with a2 and so on upto middle of sequence above. Now, there are no more than one odd symbol. Place it in the middle of answer. First half of answer will consist of occurences of symbol a. Second half will contains same symbols in reverse order.
Example :

take string S =  "aabcd"
cnt[a] = 2, cnt[b] = 1, cnt = 1, cnt[d] = 1.
Odd characters => b, c, d
replace ak('d') with a1('b') we get => b, c, b.
cnt[b] = 2, cnt = 1.Place odd character in middle
and 'a' and 'b' in first half and also in second half,
we get "abcba".

C++

 // CPP code for changing a string // into lexicographically smallest // pallindromic string #include using namespace std;    // Function to create a palindrome int Palindrome(string s, int n) {     unordered_map cnt;     string R = "";        // Count the occurences of     // every character in the string     for (int i = 0; i < n; i++) {         char a = s[i];         cnt[a]++;     }        // Create a string of characters     // with odd occurences     for (char i = 'a'; i <= 'z'; i++) {         if (cnt[i] % 2 != 0)             R += i;     }        int l = R.length();     int j = 0;        // Change the created string upto     // middle element and update     // count to make sure that only     // one odd character exists.     for (int i = l - 1; i >= l / 2; i--) {            // decrease the count of         // character updated         cnt[R[i]]--;         R[i] = R[j];         cnt[R[j]]++;         j++;     }        // Create three strings to make     // first half second half and     // middle one.     string first, middle, second;        for (char i = 'a'; i <= 'z'; i++) {         if (cnt[i] != 0) {                // characters with even occurrences             if (cnt[i] % 2 == 0) {                 int j = 0;                    // fill the first half.                 while (j < cnt[i] / 2) {                     first += i;                     j++;                 }             }                // character with odd occurrence             else {                 int j = 0;                    // fill the first half with                 // half of occurrence except one                 while (j < (cnt[i] - 1) / 2) {                     first += i;                     j++;                 }                    // For middle element                 middle += i;             }         }     }        // create the second half by     // reversing the first half.     second = first;     reverse(second.begin(), second.end());     string resultant = first + middle + second;     cout << resultant << endl; }    // Driver code int main() {     string S = "geeksforgeeks";     int n = S.length();     Palindrome(S, n);     return 0; }

Python3

 # Python code for changing a string # into lexicographically smallest # pallindromic string    # Function to create a palindrome def palindrome(s: str, n: int) -> int:     cnt = dict()     R = []        # Count the occurences of     # every character in the string     for i in range(n):         a = s[i]         if a in cnt:             cnt[a] += 1         else:             cnt[a] = 1        # Create a string of characters     # with odd occurences     i = 'a'     while i <= 'z':         if i in cnt and cnt[i] % 2 != 0:             R += i         i = chr(ord(i) + 1)        l = len(R)     j = 0        # Change the created string upto     # middle element and update     # count to make sure that only     # one odd character exists.     for i in range(l - 1, (l // 2) - 1, -1):            # decrease the count of         # character updated         if R[i] in cnt:             cnt[R[i]] -= 1         else:             cnt[R[i]] = -1            R[i] = R[j]            if R[j] in cnt:             cnt[R[j]] += 1         else:             cnt[R[j]] = 1         j += 1        # Create three strings to make     # first half second half and     # middle one.     first, middle, second = "", "", ""        i = 'a'     while i <= 'z':         if i in cnt:                # characters with even occurrences             if cnt[i] % 2 == 0:                 j = 0                    # fill the first half.                 while j < cnt[i] // 2:                     first += i                     j += 1                # character with odd occurrence             else:                 j = 0                    # fill the first half with                 # half of occurrence except one                 while j < (cnt[i] - 1) // 2:                     first += i                     j += 1                    # For middle element                 middle += i         i = chr(ord(i) + 1)        # create the second half by     # reversing the first half.     second = first     second = ''.join(reversed(second))     resultant = first + middle + second     print(resultant)    # Driver Code if __name__ == "__main__":        S = "geeksforgeeks"     n = len(S)     palindrome(S, n)    # This code is contributed by # sanjeev2552

Output:

eefgksoskgfee

GeeksforGeeks has prepared a complete interview preparation course with premium videos, theory, practice problems, TA support and many more features. Please refer Placement 100 for details

My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.

Improved By : sanjeev2552

Article Tags :
Practice Tags :

Be the First to upvote.

Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.