Largest palindromic number by permuting digits
Given N(very large), the task is to print the largest palindromic number obtained by permuting the digits of N. If it is not possible to make a palindromic number, then print an appropriate message.
Examples :
Input : 313551
Output : 531135
Explanations : 531135 is the largest number
which is a palindrome, 135531, 315513 and other
numbers can also be formed but we need the highest
of all of the palindromes.
Input : 331
Output : 313
Input : 3444
Output : Palindrome cannot be formed
Naive Approach: The naive approach will be to try all the permutations possible, and print the largest of such combinations, which is a palindrome.
Efficient Approach:
An efficient approach will be to use the Greedy algorithm. Since the number is large, store the number in a string. Store the count of occurrences of every digit in the given number on a map. Check if it is possible to form a palindrome or not. If the digits of the given number can be rearranged to form a palindrome, then apply the greedy approach to obtain the number. Check for the occurrence of every digit (9 to 0), and place every available digit at the front and back.
Initially, the front pointer will be at index 0, as the largest digit will be placed at first to make the number a large one. With every step, move the front pointer 1 position ahead. If the digit occurs an odd number of times, then place one digit in the middle and the rest of the even number of digits at front and back. Keep repeating the process (map[digit]/2) the number of times for a single digit. After placing a particular digit that occurs an even number of times at the front and back, move the front pointer one step ahead. The placing is done till map[digit] is 0. The char array will have the largest palindromic number possible after the completion of the placing of digits greedily.
In the worst case, the time complexity will be O(10 * (length of string/2)), in case the number consists of the same digit at every position.
Below is the implementation of the above idea:
C++
#include <bits/stdc++.h>
using namespace std;
bool possibility(unordered_map< int , int > m,
int length, string s)
{
int countodd = 0;
for ( int i = 0; i < length; i++) {
if (m[s[i] - '0' ] & 1)
countodd++;
if (countodd > 1)
return false ;
}
return true ;
}
void largestPalindrome(string s)
{
int l = s.length();
unordered_map< int , int > m;
for ( int i = 0; i < l; i++)
m[s[i] - '0' ]++;
if (possibility(m, l, s) == false ) {
cout << "Palindrome cannot be formed" ;
return ;
}
char largest[l];
int front = 0;
for ( int i = 9; i >= 0; i--) {
if (m[i] & 1) {
largest[l / 2] = char (i + 48);
m[i]--;
while (m[i] > 0) {
largest[front] = char (i + 48);
largest[l - front - 1] = char (i + 48);
m[i] -= 2;
front++;
}
}
else {
while (m[i] > 0) {
largest[front] = char (i + 48);
largest[l - front - 1] = char (i + 48);
m[i] -= 2;
front++;
}
}
}
for ( int i = 0; i < l; i++)
cout << largest[i];
}
int main()
{
string s = "313551" ;
largestPalindrome(s);
return 0;
}
|
Java
import java.util.*;
class GFG{
static boolean possibility(HashMap<Integer,
Integer> m,
int length, String s)
{
int countodd = 0 ;
for ( int i = 0 ; i < length; i++)
{
if (m.get(s.charAt(i) - '0' ) % 2 == 1 )
countodd++;
if (countodd > 1 )
return false ;
}
return true ;
}
static void largestPalindrome(String s)
{
int l = s.length();
HashMap<Integer,
Integer> m = new HashMap<>();
for ( int i = 0 ; i < l; i++)
if (m.containsKey(s.charAt(i) - '0' ))
m.put(s.charAt(i) - '0' ,
m.get(s.charAt(i) - '0' ) + 1 );
else
m.put(s.charAt(i) - '0' , 1 );
if (possibility(m, l, s) == false )
{
System.out.print( "Palindrome cannot be formed" );
return ;
}
char []largest = new char [l];
int front = 0 ;
for ( int i = 9 ; i >= 0 ; i--)
{
if (m.containsKey(i) &&
m.get(i)% 2 == 1 )
{
largest[l / 2 ] = ( char )(i + 48 );
m.put(i, m.get(i)- 1 );
while (m.get(i) > 0 )
{
largest[front] = ( char )(i + 48 );
largest[l - front - 1 ] =
( char )(i + 48 );
m.put(i, m.get(i) - 2 );
front++;
}
}
else
{
while (m.containsKey(i) &&
m.get(i) > 0 )
{
largest[front] = ( char )(i + 48 );
largest[l - front - 1 ] =
( char )(i + 48 );
m.put(i, m.get(i) - 2 );
front++;
}
}
}
for ( int i = 0 ; i < l; i++)
System.out.print(largest[i]);
}
public static void main(String[] args)
{
String s = "313551" ;
largestPalindrome(s);
}
}
|
Python3
from collections import defaultdict
def possibility(m, length, s):
countodd = 0
for i in range ( 0 , length):
if m[ int (s[i])] & 1 :
countodd + = 1
if countodd > 1 :
return False
return True
def largestPalindrome(s):
l = len (s)
m = defaultdict( lambda : 0 )
for i in range ( 0 , l):
m[ int (s[i])] + = 1
if possibility(m, l, s) = = False :
print ( "Palindrome cannot be formed" )
return
largest = [ None ] * l
front = 0
for i in range ( 9 , - 1 , - 1 ):
if m[i] & 1 :
largest[l / / 2 ] = chr (i + 48 )
m[i] - = 1
while m[i] > 0 :
largest[front] = chr (i + 48 )
largest[l - front - 1 ] = chr (i + 48 )
m[i] - = 2
front + = 1
else :
while m[i] > 0 :
largest[front] = chr (i + 48 )
largest[l - front - 1 ] = chr (i + 48 )
m[i] - = 2
front + = 1
for i in range ( 0 , l):
print (largest[i], end = "")
if __name__ = = "__main__" :
s = "313551"
largestPalindrome(s)
|
C#
using System;
using System.Collections.Generic;
class GFG{
static bool possibility(Dictionary< int , int > m,
int length, string s)
{
int countodd = 0;
for ( int i = 0; i < length; i++)
{
if ((m[s[i] - '0' ] & 1) != 0)
countodd++;
if (countodd > 1)
return false ;
}
return true ;
}
static void largestPalindrome( string s)
{
int l = s.Length;
Dictionary< int ,
int > m = new Dictionary< int ,
int >();
for ( int i = 0; i < 10; i++)
m[i] = 0;
for ( int i = 0; i < l; i++)
m[s[i] - '0' ]++;
if (possibility(m, l, s) == false )
{
Console.Write( "Palindrome cannot be formed" );
return ;
}
char []largest = new char [l];
int front = 0;
for ( int i = 9; i >= 0; i--)
{
if ((m[i] & 1) != 0)
{
largest[l / 2] = ( char )(i + '0' );
m[i]--;
while (m[i] > 0)
{
largest[front] = ( char )(i + '0' );
largest[l - front - 1] = ( char )(i + '0' );
m[i] -= 2;
front++;
}
}
else
{
while (m[i] > 0)
{
largest[front] = ( char )(i + '0' );
largest[l - front - 1] = ( char )(i + '0' );
m[i] -= 2;
front++;
}
}
}
for ( int i = 0; i < l; i++)
{
Console.Write(largest[i]);
}
}
public static void Main( string [] args)
{
string s = "313551" ;
largestPalindrome(s);
}
}
|
Javascript
<script>
function possibility(m,length, s)
{
var countodd = 0;
for ( var i = 0; i < length; i++) {
if (m.get(s.charCodeAt(i) - 48) & 1)
countodd++;
if (countodd > 1)
return false ;
}
return true ;
}
function largestPalindrome(s)
{
var l = s.length;
var m = new Map();
for ( var i = 0; i < l; i++){
if (m.has(s.charCodeAt(i) - 48))
m.set(s.charCodeAt(i) - 48, m.get(s.charCodeAt(i) - 48)+1);
else
m.set(s.charCodeAt(i) - 48, 1);
}
if (possibility(m, l, s) == false ) {
document.write( "Palindrome cannot be formed" );
return ;
}
var largest = new Array(l);
var front = 0;
for ( var i = 9; i >= 0; i--) {
if (m.get(i) & 1) {
largest[(Math.floor(l / 2))] = String.fromCharCode(i + 48);
m.set(i, m.get(i)-1);
while (m.get(i) > 0) {
largest[front] = String.fromCharCode(i + 48);
largest[l - front - 1] = String.fromCharCode(i + 48);
m.set(i, m.get(i)-2);
front++;
}
}
else {
while (m.get(i) > 0){
largest[front] = String.fromCharCode(i + 48);
largest[l - front - 1] = String.fromCharCode(i + 48);
m.set(i, m.get(i)-2);
front++;
}
}
}
for ( var i = 0; i < l; i++)
document.write(largest[i]);
}
var s = "313551" ;
largestPalindrome(s);
</script>
|
Time Complexity: O(N), as we are using loop to traverse N times.
Auxiliary Space: O(N), as we are using extra space for map m and largest array.
Last Updated :
24 Mar, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...