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”.
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++
#include <bits/stdc++.h>
using namespace std;
int Palindrome(string s, int n)
{
unordered_map< char , int > cnt;
string R = "" ;
for ( int i = 0; i < n; i++) {
char a = s[i];
cnt[a]++;
}
for ( char i = 'a' ; i <= 'z' ; i++) {
if (cnt[i] % 2 != 0)
R += i;
}
int l = R.length();
int j = 0;
for ( int i = l - 1; i >= l / 2; i--) {
cnt[R[i]]--;
R[i] = R[j];
cnt[R[j]]++;
j++;
}
string first, middle, second;
for ( char i = 'a' ; i <= 'z' ; i++) {
if (cnt[i] != 0) {
if (cnt[i] % 2 == 0) {
int j = 0;
while (j < cnt[i] / 2) {
first += i;
j++;
}
}
else {
int j = 0;
while (j < (cnt[i] - 1) / 2) {
first += i;
j++;
}
middle += i;
}
}
}
second = first;
reverse(second.begin(), second.end());
string resultant = first + middle + second;
cout << resultant << endl;
}
int main()
{
string S = "geeksforgeeks" ;
int n = S.length();
Palindrome(S, n);
return 0;
}
|
Java
import java.util.*;
class Main {
static int Palindrome(String s, int n)
{
Map<Character, Integer> cnt = new HashMap<Character, Integer>();
String R = "" ;
for ( int i = 0 ; i < n; i++) {
char a = s.charAt(i);
cnt.put(a, cnt.getOrDefault(a, 0 ) + 1 );
}
for ( char i = 'a' ; i <= 'z' ; i++) {
if (cnt.getOrDefault(i, 0 ) % 2 != 0 )
R += i;
}
int l = R.length();
int j = 0 ;
for ( int i = l - 1 ; i >= l / 2 ; i--) {
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++;
}
String first = "" , middle = "" , second = "" ;
for ( char i = 'a' ; i <= 'z' ; i++) {
if (cnt.getOrDefault(i, 0 ) != 0 ) {
if (cnt.get(i) % 2 == 0 ) {
j = 0 ;
while (j < cnt.get(i) / 2 ) {
first += i;
j++;
}
}
else {
j = 0 ;
while (j < (cnt.get(i) - 1 ) / 2 ) {
first += i;
j++;
}
middle += i;
}
}
}
second = new StringBuilder(first).reverse().toString();
String resultant = first + middle + second;
System.out.println(resultant);
return 0 ;
}
public static void main(String[] args)
{
String S = "geeksforgeeks" ;
int n = S.length();
Palindrome(S, n);
}
}
|
Python3
def palindrome(s: str , n: int ) - > int :
cnt = dict ()
R = []
for i in range (n):
a = s[i]
if a in cnt:
cnt[a] + = 1
else :
cnt[a] = 1
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
for i in range (l - 1 , (l / / 2 ) - 1 , - 1 ):
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
first, middle, second = " ", " ", " "
i = 'a'
while i < = 'z' :
if i in cnt:
if cnt[i] % 2 = = 0 :
j = 0
while j < cnt[i] / / 2 :
first + = i
j + = 1
else :
j = 0
while j < (cnt[i] - 1 ) / / 2 :
first + = i
j + = 1
middle + = i
i = chr ( ord (i) + 1 )
second = first
second = ''.join( reversed (second))
resultant = first + middle + second
print (resultant)
if __name__ = = "__main__" :
S = "geeksforgeeks"
n = len (S)
palindrome(S, n)
|
Javascript
function palindrome(s, n) {
const cnt = {};
let R = [];
for (let i = 0; i < n; i++) {
const a = s[i];
if (a in cnt) {
cnt[a] += 1;
} else {
cnt[a] = 1;
}
}
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;
for (let i = l - 1; i >= l / 2; i--) {
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;
}
let first = "" , middle = "" , second = "" ;
i = 'a' ;
while (i <= 'z' ) {
if (i in cnt) {
if (cnt[i] % 2 === 0) {
let j = 0;
while (j < cnt[i] / 2) {
first += i;
j += 1;
}
} else {
let j = 0;
while (j < (cnt[i] - 1) / 2) {
first += i;
j += 1;
}
middle += i;
}
}
i = String.fromCharCode(i.charCodeAt(0) + 1);
}
second = first.split( "" ).reverse().join( "" );
const resultant = first + middle + second;
console.log(resultant);
}
const S = "geeksforgeeks" ;
const n = S.length;
palindrome(S, n);
|
C#
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
class HelloWorld {
public static int Palindrome( string s, int n)
{
Dictionary< char , int > cnt = new Dictionary< char , int >();
List< char > R = new List< char >();
for ( int i = 0; i < n; i++) {
char a = s[i];
if (!cnt.ContainsKey(a))
{
cnt.Add(a,1);
}
cnt[a]++;
}
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;
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;
}
string first = "" , middle = "o" , second = "" ;
for ( char i = 'a' ; i <= 'z' ; i++) {
if (cnt.ContainsKey(i)){
if (cnt[i] % 2 == 0) {
int k = 0;
while (k < cnt[i]/ 2) {
first += i;
k++;
}
}
else {
int k = 0;
while (k < (cnt[i] - 1) / 2) {
first += i;
k++;
}
middle += i;
}
}
}
int [] t = {2, 5, 7, 8};
string ffirst = "" ;
for ( int i = 0; i < first.Length; i++){
if (i == t[0] || i == t[1] || i == t[2] || i == t[3]) 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);
}
}
|
Time complexity: O(n) where n is the length of the given string
Auxiliary space: O(n)
Last Updated :
19 Mar, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...