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++
// 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 number bool 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 number void 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 Code int main() { string s = "313551" ; largestPalindrome(s); return 0; } |
Java
// JAVA program to print the // largest palindromic number // by permuting digits of a number import java.util.*; class GFG{ // Function to check if a number can be // permuted to form a palindrome number static 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 number static 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 Code public static void main(String[] args) { String s = "313551" ; largestPalindrome(s); } } // This code is contributed by Rajput-Ji |
Python3
# Python3 program to print the largest palindromic # number by permuting digits of a number from collections import defaultdict # Function to check if a number can be # permuted to form a palindrome number def 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 number def 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 Code if __name__ = = "__main__" : s = "313551" largestPalindrome(s) # This code is contributed by Rituraj Jain |
C#
// C# program to print the largest // palindromic number by permuting // digits of a number using System; using System.Collections.Generic; class GFG{ // Function to check if a number can be // permuted to form a palindrome number static 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 number static 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 Code public static void Main( string [] args) { string s = "313551" ; largestPalindrome(s); } } // This code is contributed by rutvik_56 |
Javascript
<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 number function 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 number function 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.get(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 code var s = "313551" ; largestPalindrome(s); // This code contributed by shubhamsingh10 </script> |
531135
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.
Please Login to comment...