📜  计算字符串中的最大长度回文

📅  最后修改于: 2021-04-29 14:03:37             🧑  作者: Mango

给定一个字符串,计算存在多少个最大长度的回文(不必是子字符串)
例子:

Input : str = "ababa"
Output: 2
Explanation : 
palindromes of maximum of lenghts are  :
 "ababa", "baaab" 

Input : str = "ababab"
Output: 4
Explanation : 
palindromes of maximum of lenghts are  :
 "ababa", "baaab", "abbba", "babab"

方法回文可以表示为“ str + t + reverse(str)”
注意:对于长度相等的回文字符串, “ t”为空
计算可以用多少种方式形成“ str”,然后乘以“ t”(省略的单个字符数)。

令c i为字符串中字符出现的次数。考虑以下情况:
1.如果c i是偶数。那么每个最大回文集的一半将恰好包含字母f i = c i / 2。
2.如果c i是奇数。然后,每个最大回文集的一半将完全包含字母f i =(c i – 1)/ 2。
令k为奇数c i的数量。如果k = 0,则最大回文长度将是偶数;否则它将是奇数,并且将恰好有k个可能的中间字母,即我们可以将该字母设置为回文的中间。

n个对象与n 1个相同类型1的对象,n 2个相同类型2的对象以及n3个类型3的相同对象的排列数目为n! /(n1!* n2!* n3!)
因此,这里的字符总数为f a + f b + f a +……。+ f y + f z 。因此,排列数为(f a + f b + f a +……。+ f y + f z )! /! f b !…f y !f z !。
现在,如果K不为0,答案显然就是k *(f a + f b + f a +……。+ f y + f z +)! /! f b !…f y !f z

下面是以上的实现。

C++
// C++ implementation for counting
// maximum length palindromes
#include 
using namespace std;
  
// factorial of a number
int fact(int n)
{
    int ans = 1;
    for (int i = 1; i <= n; i++)    
        ans = ans * i;
    return (ans);
}
  
// function to count maximum length palindromes.
int numberOfPossiblePallindrome(string str, int n)
{   
    // Count number of occurrence
    // of a charterer in the string
    unordered_map mp;
    for (int i = 0; i < n; i++) 
        mp[str[i]]++;
  
    int k = 0;  // Count of singles
    int num = 0;  // numerator of result
    int den = 1;  // denominator of result
    int fi;  
    for (auto it = mp.begin(); it != mp.end(); ++it)
    {
        // if frequency is even 
        // fi = ci / 2
        if (it->second % 2 == 0) 
            fi = it->second / 2;
          
        // if frequency is odd 
        // fi = ci - 1 / 2.
        else 
        {
            fi = (it->second - 1) / 2; 
            k++;
        }
  
        // sum of all frequencies
        num = num + fi; 
          
        // product of factorial of
        // every frequency
        den = den * fact(fi); 
    }
      
    // if all character are unique 
    // so there will be no pallindrome, 
    // so if num != 0 then only we are
    // finding the factorial
    if (num != 0) 
        num = fact(num);
          
    int ans = num / den; 
      
    if (k != 0)
    {
        // k are the single 
        // elements that can be
        // placed in middle
        ans = ans * k;
    }
      
    return (ans);
}
  
// Driver program
int main()
{
    char str[] = "ababab";
    int n = strlen(str);
    cout << numberOfPossiblePallindrome(str, n);
    return 0;
}


Java
// Java implementation for counting
// maximum length palindromes
import java.util.*;
  
class GFG
{
  
// factorial of a number
static int fact(int n)
{
    int ans = 1;
    for (int i = 1; i <= n; i++) 
        ans = ans * i;
    return (ans);
}
  
// function to count maximum length palindromes.
static int numberOfPossiblePallindrome(String str, int n)
{ 
    // Count number of occurrence
    // of a charterer in the string
    Map mp = new HashMap<>();
    for (int i = 0; i < n; i++) 
        mp.put( str.charAt(i),mp.get( str.charAt(i))==null?
                1:mp.get( str.charAt(i))+1);
  
    int k = 0; // Count of singles
    int num = 0; // numerator of result
    int den = 1; // denominator of result
    int fi; 
    for (Map.Entry it : mp.entrySet()) 
    {
        // if frequency is even 
        // fi = ci / 2
        if (it.getValue() % 2 == 0) 
            fi = it.getValue() / 2;
          
        // if frequency is odd 
        // fi = ci - 1 / 2.
        else
        {
            fi = (it.getValue() - 1) / 2; 
            k++;
        }
  
        // sum of all frequencies
        num = num + fi; 
          
        // product of factorial of
        // every frequency
        den = den * fact(fi); 
    }
      
    // if all character are unique 
    // so there will be no pallindrome, 
    // so if num != 0 then only we are
    // finding the factorial
    if (num != 0) 
        num = fact(num);
          
    int ans = num / den; 
      
    if (k != 0)
    {
        // k are the single 
        // elements that can be
        // placed in middle
        ans = ans * k;
    }
      
    return (ans);
}
  
// Driver code
public static void main(String[] args)
{
    String str = "ababab";
    int n = str.length();
    System.out.println(numberOfPossiblePallindrome(str, n));
}
}
  
// This code is contributed by Princi Singh


Python3
# Python3 implementation for counting
# maximum length palindromes
import math as mt
  
# factorial of a number
def fact(n):
    ans = 1
    for i in range(1, n + 1): 
        ans = ans * i
    return (ans)
  
# function to count maximum length palindromes.
def numberOfPossiblePallindrome(string, n):
      
    # Count number of occurrence
    # of a charterer in the string
    mp = dict()
    for i in range(n):
        if string[i] in mp.keys():
            mp[string[i]] += 1
        else: 
            mp[string[i]] = 1
  
    k = 0 # Count of singles
    num = 0 # numerator of result
    den = 1 # denominator of result
    fi = 0
    for it in mp:
      
        # if frequency is even 
        # fi = ci / 2
        if (mp[it] % 2 == 0):
            fi = mp[it] // 2
          
        # if frequency is odd 
        # fi = ci - 1 / 2.
        else:
          
            fi = (mp[it] - 1) // 2
            k += 1
  
        # sum of all frequencies
        num = num + fi 
          
        # product of factorial of
        # every frequency
        den = den * fact(fi) 
      
    # if all character are unique 
    # so there will be no pallindrome, 
    # so if num != 0 then only we are
    # finding the factorial
    if (num != 0): 
        num = fact(num)
          
    ans = num //den 
      
    if (k != 0):
      
        # k are the single 
        # elements that can be
        # placed in middle
        ans = ans * k
      
    return (ans)
  
# Driver Code
string = "ababab"
n = len(string)
print(numberOfPossiblePallindrome(string, n))
  
# This code is contributed by 
# Mohit kumar 29


C#
// C# implementation for counting
// maximum length palindromes
using System;
using System.Collections.Generic;
      
class GFG
{
  
// factorial of a number
static int fact(int n)
{
    int ans = 1;
    for (int i = 1; i <= n; i++) 
        ans = ans * i;
    return (ans);
}
  
// function to count maximum length palindromes.
static int numberOfPossiblePallindrome(String str, int n)
{ 
    // Count number of occurrence
    // of a charterer in the string
    Dictionary mp = new Dictionary();
    for (int i = 0 ; i < n; i++)
    {
        if(mp.ContainsKey(str[i]))
        {
            var val = mp[str[i]];
            mp.Remove(str[i]);
            mp.Add(str[i], val + 1); 
        }
        else
        {
            mp.Add(str[i], 1);
        }
    }
  
    int k = 0; // Count of singles
    int num = 0; // numerator of result
    int den = 1; // denominator of result
    int fi; 
    foreach(KeyValuePair it in mp)
    {
        // if frequency is even 
        // fi = ci / 2
        if (it.Value % 2 == 0) 
            fi = it.Value / 2;
          
        // if frequency is odd 
        // fi = ci - 1 / 2.
        else
        {
            fi = (it.Value - 1) / 2; 
            k++;
        }
  
        // sum of all frequencies
        num = num + fi; 
          
        // product of factorial of
        // every frequency
        den = den * fact(fi); 
    }
      
    // if all character are unique 
    // so there will be no pallindrome, 
    // so if num != 0 then only we are
    // finding the factorial
    if (num != 0) 
        num = fact(num);
          
    int ans = num / den; 
      
    if (k != 0)
    {
        // k are the single 
        // elements that can be
        // placed in middle
        ans = ans * k;
    }
      
    return (ans);
}
  
// Driver code
public static void Main(String[] args)
{
    String str = "ababab";
    int n = str.Length;
    Console.WriteLine(numberOfPossiblePallindrome(str, n));
}
}
  
// This code is contributed by 29AjayKumar


输出:

4

时间复杂度: O(n)