Largest palindromic number by permuting digits - GeeksforGeeks

31 May, 2021
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++
Java
Python3
C#
Javascript
// CPP program to print the largest palindromic// number by permuting digits of a number#include <bits/stdc++.h>using namespace std;  // function to check if a number can be// permuted to form a palindrome numberbool possibility(unordered_map<int, int> m,                 int length, string s){    // counts the occurrence of number which is odd    int countodd = 0;    for (int i = 0; i < length; i++) {         // if occurrence is odd        if (m[s[i] - '0'] & 1)            countodd++;          // if number exceeds 1        if (countodd > 1)            return false;    }      return true;}  // function to print the largest palindromic number// by permuting digits of a numbervoid largestPalindrome(string s){      // string length    int l = s.length();      // map that marks the occurrence of a number    unordered_map<int, int> m;    for (int i = 0; i < l; i++)        m[s[i] - '0']++;      // check the possibility of a palindromic number    if (possibility(m, l, s) == false) {        cout << "Palindrome cannot be formed";        return;    }      // string array that stores the largest    // permuted palindromic number    char largest[l];      // pointer of front    int front = 0;      // greedily start from 9 to 0 and place the    // greater number in front and odd in the    // middle    for (int i = 9; i >= 0; i--) {          // if the occurrence of number is odd        if (m[i] & 1) {              // place one odd occurring number            // in the middle            largest[l / 2] = char(i + 48);              // decrease the count            m[i]--;              // place the rest of numbers greedily            while (m[i] > 0) {                largest[front] = char(i + 48);                largest[l - front - 1] = char(i + 48);                m[i] -= 2;                front++;            }        }        else {             // if all numbers occur even times,            // then place greedily            while (m[i] > 0) {                  // place greedily at front                largest[front] = char(i + 48);                largest[l - front - 1] = char(i + 48);                  // 2 numbers are placed, so decrease the count                m[i] -= 2;                  // increase placing position                front++;            }        }    }      // print the largest string thus formed    for (int i = 0; i < l; i++)        cout << largest[i];}  // Driver Codeint main(){    string s = "313551";    largestPalindrome(s);    return 0;}
// JAVA program to print the// largest palindromic number// by permuting digits of a numberimport java.util.*;class GFG{  // Function to check if a number can be// permuted to form a palindrome numberstatic boolean possibility(HashMap<Integer,                                   Integer> m,                           int length, String s){  // counts the occurrence of number  // which is odd  int countodd = 0;     for (int i = 0; i < length; i++)  {    // if occurrence is odd    if (m.get(s.charAt(i) - '0') % 2 == 1)      countodd++;     // if number exceeds 1    if (countodd > 1)      return false;  }   return true;}  // function to print the largest// palindromic number by permuting// digits of a numberstatic void largestPalindrome(String s){  // String length  int l = s.length();   // map that marks the occurrence  // of a number  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);   // check the possibility of a  // palindromic number  if (possibility(m, l, s) == false)  {    System.out.print("Palindrome cannot be formed");    return;  }   // String array that stores  // the largest permuted  // palindromic number  char []largest = new char[l];   // pointer of front  int front = 0;   // greedily start from 9 to 0  // and place the greater number  // in front and odd in the middle  for (int i = 9; i >= 0; i--)  {    // if the occurrence of    // number is odd    if (m.containsKey(i) &&        m.get(i)%2==1)    {      // place one odd occurring      // number in the middle      largest[l / 2] = (char)(i + 48);       // decrease the count      m.put(i, m.get(i)-1);       // place the rest of      // numbers greedily      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    {      // if all numbers occur even      // times, then place greedily      while (m.containsKey(i) &&             m.get(i) > 0)      {        // place greedily at front        largest[front] = (char)(i + 48);        largest[l - front - 1] =               (char)(i + 48);         // 2 numbers are placed,        // so decrease the count        m.put(i, m.get(i) - 2);         // increase placing position        front++;      }    }  }   // print the largest String  // thus formed  for (int i = 0; i < l; i++)    System.out.print(largest[i]);} // Driver Codepublic static void main(String[] args){  String s = "313551";  largestPalindrome(s);}} // This code is contributed by Rajput-Ji
# Python3 program to print the largest palindromic# number by permuting digits of a numberfrom collections import defaultdict # Function to check if a number can be# permuted to form a palindrome numberdef possibility(m, length, s):     # counts the occurrence of    # number which is odd    countodd = 0    for i in range(0, length):         # if occurrence is odd        if m[int(s[i])] & 1:            countodd += 1         # if number exceeds 1        if countodd > 1:            return False         return True # Function to print the largest palindromic# number by permuting digits of a numberdef largestPalindrome(s):     # string length    l = len(s)     # map that marks the occurrence of a number    m = defaultdict(lambda:0)    for i in range(0, l):        m[int(s[i])] += 1     # check the possibility of a    # palindromic number    if possibility(m, l, s) == False:        print("Palindrome cannot be formed")        return         # string array that stores the largest    # permuted palindromic number    largest = [None] * l     # pointer of front    front = 0     # greedily start from 9 to 0 and place the    # greater number in front and odd in the middle    for i in range(9, -1, -1):         # if the occurrence of number is odd        if m[i] & 1:             # place one odd occurring number            # in the middle            largest[l // 2] = chr(i + 48)             # decrease the count            m[i] -= 1             # place the rest of numbers greedily            while m[i] > 0:                largest[front] = chr(i + 48)                largest[l - front - 1] = chr(i + 48)                m[i] -= 2                front += 1                     else:             # if all numbers occur even times,            # then place greedily            while m[i] > 0:                 # place greedily at front                largest[front] = chr(i + 48)                largest[l - front - 1] = chr(i + 48)                 # 2 numbers are placed,                # so decrease the count                m[i] -= 2                 # increase placing position                front += 1     # print the largest string thus formed    for i in range(0, l):        print(largest[i], end = "") # Driver Codeif __name__ == "__main__":     s = "313551"    largestPalindrome(s)     # This code is contributed by Rituraj Jain
// C# program to print the largest// palindromic number by permuting// digits of a numberusing System;using System.Collections.Generic; class GFG{ // Function to check if a number can be// permuted to form a palindrome numberstatic bool possibility(Dictionary<int, int> m,                        int length, string s){         // Counts the occurrence of number    // which is odd    int countodd = 0;         for(int i = 0; i < length; i++)    {                 // If occurrence is odd        if ((m[s[i] - '0'] & 1) != 0)            countodd++;         // If number exceeds 1        if (countodd > 1)            return false;    }    return true;} // Function to print the largest palindromic// number by permuting digits of a numberstatic void largestPalindrome(string s){         // string length    int l = s.Length;     // Map that marks the occurrence of a number    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']++;     // Check the possibility of a    // palindromic number    if (possibility(m, l, s) == false)    {        Console.Write("Palindrome cannot be formed");        return;    }     // string array that stores the largest    // permuted palindromic number    char []largest = new char[l];     // Pointer of front    int front = 0;     // Greedily start from 9 to 0 and place the    // greater number in front and odd in the    // middle    for(int i = 9; i >= 0; i--)    {                 // If the occurrence of number is odd        if ((m[i] & 1) != 0)        {                         // Place one odd occurring number            // in the middle            largest[l / 2] = (char)(i + '0');             // Decrease the count            m[i]--;             // Place the rest of numbers greedily            while (m[i] > 0)            {                largest[front] = (char)(i + '0');                largest[l - front - 1] = (char)(i + '0');                m[i] -= 2;                front++;            }        }        else        {                         // If all numbers occur even times,            // then place greedily            while (m[i] > 0)            {                                 // Place greedily at front                largest[front] = (char)(i + '0');                largest[l - front - 1] = (char)(i + '0');                 // 2 numbers are placed, so                // decrease the count                m[i] -= 2;                 // Increase placing position                front++;            }        }    }     // Print the largest string thus formed    for(int i = 0; i < l; i++)    {        Console.Write(largest[i]);    }} // Driver Codepublic static void Main(string[] args){    string s = "313551";         largestPalindrome(s);}} // This code is contributed by rutvik_56
<script>// Javascript program to print the largest palindromic// number by permuting digits of a number   // function to check if a number can be// permuted to form a palindrome numberfunction possibility(m,length, s){    // counts the occurrence of number which is odd    var countodd = 0;    for (var i = 0; i < length; i++) {          // if occurrence is odd        if (m.get(s.charCodeAt(i) - 48) & 1)            countodd++;           // if number exceeds 1        if (countodd > 1)            return false;    }       return true;}   // function to print the largest palindromic number// by permuting digits of a numberfunction largestPalindrome(s){       // string length    var l = s.length;       // map that marks the occurrence of a number    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);                }       // check the possibility of a palindromic number    if (possibility(m, l, s) == false) {        document.write("Palindrome cannot be formed");        return;    }       // string array that stores the largest    // permuted palindromic number    var largest = new Array(l);       // pointer of front    var front = 0;       // greedily start from 9 to 0 and place the    // greater number in front and odd in the    // middle    for (var i = 9; i >= 0; i--) {                 // if the occurrence of number is odd        if (m.has(i) & 1) {               // place one odd occurring number            // in the middle            largest[Math.floor(l / 2)] = String.fromCharCode(i + 48);               // decrease the count            m.set(i, m.get(i)-1);               // place the rest of numbers greedily            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 {              // if all numbers occur even times,            // then place greedily            while (m.get(i) > 0){                   // place greedily at front                largest[front] = String.fromCharCode(i + 48);                largest[l - front - 1] = String.fromCharCode(i + 48);                   // 2 numbers are placed, so decrease the count                m.set(i, m.get(i)-2);                   // increase placing position                front++;            }        }    }       // print the largest string thus formed    for (var i = 0; i < l; i++)        document.write(largest[i]);}// driver codevar s = "313551";largestPalindrome(s);// This code contributed by shubhamsingh10</script>
531135
 
Time Complexity: O(n), where n is the length of the string. 
rituraj_jain
rutvik_56
Rajput-Ji
SHUBHAMSINGH10
cpp-unordered_map
palindrome
Greedy
Hash
Strings
Hash
Strings
Greedy
palindrome
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
Program for Least Recently Used (LRU) Page Replacement algorithm
Difference between Prim's and Kruskal's algorithm for MST
Program for Shortest Job First (SJF) scheduling | Set 2 (Preemptive)
Program for First Fit algorithm in Memory Management
Program for Best Fit algorithm in Memory Management
Given an array A[] and a number x, check for pair in A[] with sum as x (aka Two Sum)
Internal Working of HashMap in Java
Hashing | Set 1 (Introduction)
Hashing | Set 3 (Open Addressing)
Hashing | Set 2 (Separate Chaining)