📜  按排列数字排列的最大回文数

📅  最后修改于: 2021-05-04 22:35:03             🧑  作者: Mango

给定N(非常大),任务是打印通过排列N的数字而获得的最大回文数。如果不可能生成回文数,则打印适当的消息。
例子 :

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 

幼稚的方法:幼稚的方法将尝试所有可能的排列,并打印出此类回文中最大的组合。
高效的方法:一种有效的方法是使用贪婪算法。由于数字很大,因此将数字存储在字符串。将给定数字中每个数字的出现次数存储在地图中。检查是否可能形成回文。如果给定数字的数字可以重新排列以形成回文,则可以使用贪婪方法来获取数字。检查是否出现每个数字(9到0),并将每个可用数字放在前面和后面。最初,前指针将在索引0处,因为最大的数字将首先放置以使数字大。每走一步,将前指针向前移动1个位置。如果该数字出现奇数次,则将一个数字放在偶数个数字的中间和其余部分的前面和后面。保持重复处理(map [digit] / 2)次的位数。在前面和后面放置偶数次的特定数字后,将前指针向前移动一级。放置完成,直到map [digit]为0。char数组将贪婪地完成数字放置后,将具有最大的回文数。
在最坏的情况下,如果数字在每个位置都包含相同的数字,则时间复杂度将为O(10 *(字符串的长度/ 2))
下面是上述想法的实现:

C++
// CPP program to print the largest palindromic
// number by permuting digits of a number
#include 
using namespace std;
  
// function to check if a number can be
// permuted to form a palindrome number
bool possibility(unordered_map 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 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 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 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 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 m = new Dictionary();
     
    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


输出:
531135



时间复杂度: O(n),其中n是字符串的长度。