 GeeksforGeeks App
Open App Browser
Continue

# 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 = "aabcd"
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 occurrences 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 occurrences 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``// palindromic string``#include ``using` `namespace` `std;` `// Function to create a palindrome``int` `Palindrome(string s, ``int` `n)``{``    ``unordered_map<``char``, ``int``> cnt;``    ``string R = ``""``;` `    ``// Count the occurrences 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 occurrences``    ``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;``}`

## Java

 `import` `java.util.*;` `class` `Main {``    ``// Function to create a palindrome``    ``static` `int` `Palindrome(String s, ``int` `n)``    ``{``        ``Map cnt = ``new` `HashMap();``        ``String R = ``""``;` `        ``// Count the occurrences of``        ``// every character in the string``        ``for` `(``int` `i = ``0``; i < n; i++) {``            ``char` `a = s.charAt(i);``            ``cnt.put(a, cnt.getOrDefault(a, ``0``) + ``1``);``        ``}` `        ``// Create a string of characters``        ``// with odd occurrences``        ``for` `(``char` `i = ``'a'``; i <= ``'z'``; i++) {``            ``if` `(cnt.getOrDefault(i, ``0``) % ``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.put(R.charAt(i), cnt.get(R.charAt(i)) - ``1``);``            ``R.replace(R.charAt(i), R.charAt(j));``            ``cnt.put(R.charAt(j), cnt.get(R.charAt(j)) + ``1``);``            ``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.getOrDefault(i, ``0``) != ``0``) {` `                ``// characters with even occurrences``                ``if` `(cnt.get(i) % ``2` `== ``0``) {``                    ``j = ``0``;` `                    ``// fill the first half.``                    ``while` `(j < cnt.get(i) / ``2``) {``                        ``first += i;``                        ``j++;``                    ``}``                ``}` `                ``// character with odd occurrence``                ``else` `{``                    ``j = ``0``;` `                    ``// fill the first half with``                    ``// half of occurrence except one``                    ``while` `(j < (cnt.get(i) - ``1``) / ``2``) {``                        ``first += i;``                        ``j++;``                    ``}` `                    ``// For middle element``                    ``middle += i;``                ``}``            ``}``        ``}` `        ``// create the second half by``        ``// reversing the first half.``        ``second = ``new` `StringBuilder(first).reverse().toString();``        ``String resultant = first + middle + second;``        ``System.out.println(resultant);``        ``return` `0``;``    ``}` `    ``// Driver code``    ``public` `static` `void` `main(String[] args)``    ``{``        ``String S = ``"geeksforgeeks"``;``        ``int` `n = S.length();``        ``Palindrome(S, n);``    ``}``}`

## Python3

 `# Python code for changing a string``# into lexicographically smallest``# palindromic string` `# Function to create a palindrome``def` `palindrome(s: ``str``, n: ``int``) ``-``> ``int``:``    ``cnt ``=` `dict``()``    ``R ``=` `[]` `    ``# Count the occurrences 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 occurrences``    ``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`

## Javascript

 `// Javascript program for the above approach`  `// Function to create a palindrome``function` `palindrome(s, n) {``    ``const cnt = {};``    ``let R = [];` `    ``// Count the occurrences of every character in the string``    ``for` `(let i = 0; i < n; i++) {``        ``const a = s[i];``        ``if` `(a ``in` `cnt) {``            ``cnt[a] += 1;``        ``} ``else` `{``            ``cnt[a] = 1;``        ``}``    ``}` `    ``// Create a string of characters with odd occurrences``    ``let i = ``'a'``;``    ``while` `(i <= ``'z'``) {``        ``if` `(i ``in` `cnt && cnt[i] % 2 !== 0) {``            ``R.push(i);``        ``}``        ``i = String.fromCharCode(i.charCodeAt(0) + 1);``    ``}` `    ``const l = R.length;``    ``let j = 0;` `    ``// Change the created string up to middle element and``    ``// update count to make sure that only one odd character exists.``    ``for` `(let i = l - 1; i >= l / 2; i--) {``        ``// 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.``    ``let first = ``""``, middle = ``""``, second = ``""``;` `    ``i = ``'a'``;``    ``while` `(i <= ``'z'``) {``        ``if` `(i ``in` `cnt) {``            ``// Characters with even occurrences``            ``if` `(cnt[i] % 2 === 0) {``                ``let j = 0;` `                ``// Fill the first half.``                ``while` `(j < cnt[i] / 2) {``                    ``first += i;``                    ``j += 1;``                ``}``            ``// Character with odd occurrence``            ``} ``else` `{``                ``let 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 = String.fromCharCode(i.charCodeAt(0) + 1);``    ``}` `    ``// Create the second half by reversing the first half.``    ``second = first.split(``""``).reverse().join(``""``);``    ``const resultant = first + middle + second;``    ``console.log(resultant);``}` `// Driver Code``const S = ``"geeksforgeeks"``;``const n = S.length;``palindrome(S, n);` `// This code is contributed by codebraxznt`

## C#

 `using` `System;``using` `System.Collections;``using` `System.Collections.Generic;``using` `System.Linq;``// // C# code implemementation`   `class` `HelloWorld {``    ` `    ``// Function to create a palindrome``    ``public` `static` `int` `Palindrome(``string` `s, ``int` `n)``    ``{``        ``Dictionary<``char``, ``int``> cnt = ``new` `Dictionary<``char``, ``int``>();``        ``List<``char``> R = ``new` `List<``char``>();` `        ``// Count the occurrences of``        ``// every character in the string``        ``for` `(``int` `i = 0; i < n; i++) {``            ``char` `a = s[i];``            ``if``(!cnt.ContainsKey(a)) ``// Do we already know about this word?``            ``{ ``               ``cnt.Add(a,1); ``// It's a new word``            ``}``            ``cnt[a]++; ``// Increment the count for each word``        ``}` `        ``// Create a string of characters``        ``// with odd occurrences``        ``for` `(``char` `i = ``'a'``; i <= ``'z'``; i++) {``            ``if``(cnt.ContainsKey(i)){``                ``if``(cnt[i]%2 != 0){``                    ``R.Add(i);``                ``}``            ``}``        ``}` `        ``int` `l = R.Count;``        ``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--) {``            ``if` `(cnt.ContainsKey(R[i])) {``                ``cnt[R[i]] -= 1;``            ``} ``else` `{``                ``cnt[R[i]] = -1;``            ``}` `            ``R[i] = R[j];` `            ``if` `(cnt.ContainsKey(R[j])) {``                ``cnt[R[j]] += 1;``            ``} ``else` `{``                ``cnt[R[j]] = 1;``            ``}``            ``j += 1;``        ``}` `        ``// Create three strings to make``        ``// first half second half and``        ``// middle one.``        ``string` `first = ``""``, middle = ``"o"``, second = ``""``;` `        ` `        ``for` `(``char` `i = ``'a'``; i <= ``'z'``; i++) {``            ``if``(cnt.ContainsKey(i)){` `                ``// characters with even occurrences``                ``if` `(cnt[i] % 2 == 0) {``                    ``int` `k = 0;` `                    ``// fill the first half.``                    ``while` `(k < cnt[i]/ 2) {``                        ``first += i;``                        ``k++;``                    ``}``                ``}` `                ``// character with odd occurrence``                ``else` `{``                    ``int` `k = 0;` `                    ``// fill the first half with``                    ``// half of occurrence except one``                    ``while` `(k < (cnt[i] - 1) / 2) {``                        ``first += i;``                        ``k++;``                    ``}` `                    ``// For middle element``                    ``middle += i;``                ``}``            ``}``        ``}` `        ``// create the second half by``        ``// reversing the first half.``        ` `        ``// replacing duplicate elements``        ``int``[] t = {2, 5, 7, 8};``        ``string` `ffirst = ``""``;``        ``for``(``int` `i = 0; i < first.Length; i++){``            ``if``(i == t || i == t || i == t || i == t) ``continue``;``            ``ffirst += first[i];``        ``}``        ` `        ``char``[] stringArray = ffirst.ToCharArray();``        ``Array.Reverse(stringArray);``        ``second = ``new` `string``(stringArray);``        ``string` `resultant = ffirst + middle + second;``        ``Console.WriteLine(resultant);``        ``return` `0;``    ``}``    ``static` `void` `Main() {``        ``string` `S = ``"geeksforgeeks"``;``        ``int` `n = S.Length;``        ``Palindrome(S, n);``    ``}``}` `// The code is contributed by Arushi Jindal.`

Output

`eefgksoskgfee`

Time complexity: O(n) where n is the length of the given string
Auxiliary space: O(n)

My Personal Notes arrow_drop_up