Count maximum-length palindromes in a String

Given a string, count how many maximum-length palindromes are present.(It need not be a substring)
Examples:

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"

Approach A palindrome can be reprsented as “str + t + reverse(str)”.
Note: “t” is empty for even length palindromic strings.

Calculate in how many ways “str” can be made and then multiply with “t” (number of single characters left out).

Let ci be the number of occurrences of character in the string. Consider the following cases:
1. If ci is even. Then a half of every maximum palindrome will contain exactly letters fi = ci / 2.
2.If ci is odd. Then a half of every maximum palindrome will contain exactly letters fi = (ci – 1)/ 2.

Let k be the number of odd ci. If k=0, the maximum palindromes length will be even; otherwise it will be odd and there will be exactly k possible middle letters i.e., we can set this letter to the middle of palindrome.

The number of permutations of n objects with n1 identical objects of type 1, n2 identical objects of type 2,, and n3 identical objects of type 3 is n! / (n1! * n2! * n3!) .
So here we have total number of characters as fa+fb+fa+…….+fy+fz . So number of permutation is (fa+fb+fa+…….+fy+fz+)! / fa! fb!…fy!fz!.

Now If K is not 0, it’s obvious that the answer is k * (fa+fb+fa+…….+fy+fz+)! / fa! fb!…fy!fz!

Below is the implementation of the above.

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation for counting
// maximum length palindromes
#include <bits/stdc++.h>
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<char, int> 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;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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<Character,Integer> 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<Character,Integer> 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

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# 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

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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<char,int> mp = new Dictionary<char,int>();
    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<char, int> 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

chevron_right



Output:

4

Time Complexity : O(n)



My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.