Given a string str, the task is to split the string into minimum parts such that each part is of same length and each part is a palindrome. Print the required number of parts.
Examples:
Input: str = “civicbob”
Output: 8
“b”, “b”, “c”, “c”, “i”, “i”, “v” and “o” are the required partitions. “civic” and “bob” are also palindromes but they are not of equal lengthInput: str = “noonpeep”
Output: 1
Approach:
- Count the number of odd appearing characters and store it in countOdd.
- Sum the frequencies of all the even occurring characters and store it in sumEven.
- Since, no more than one odd frequency character can be a part of the same palindrome. So, if (sumEven / 2) % countOdd = 0 then the answer is countOdd as sumEven can be divided into countOdd parts.
- Else, we can still divide the odd occurring characters into the palindrome pairs. For example, if the character a appears 3 times i.e. aaa then aa can be a part of some palindrome while leaving a as odd (without affecting the original frequency).
Below is the implementation of the above approach:
C++
// C++ implementation of the approach #include <bits/stdc++.h> using namespace std; // Function to return the frequency array // for the given string int * getFrequencies(string str) { static int freq[26] = { 0 }; for ( int i = 0; i < str.length(); i++) { freq[str[i] - 'a' ]++; } return freq; } // Function to return the required count int countMinParts(string str) { int n = str.length(); int *freq = getFrequencies(str); vector< int > oddFreq, evenFreq; int i, sumEven = 0; for (i = 0; i < 26; i++) { if (freq[i] == 0) continue ; // Add frequencies of the even appearing // characters if (freq[i] % 2 == 0) evenFreq.push_back(freq[i]); // Count of the characters that appeared // odd number of times else oddFreq.push_back(freq[i]); } for (i = 0; i < evenFreq.size(); i++) { sumEven += evenFreq[i]; } // If there are no characters with odd frequency if (oddFreq.size() == 0) return 1; // If there are no characters with even frequency if (sumEven == 0) { // Only a single character with odd frequency if (oddFreq.size() == 1) return 1; // More than 1 character with odd frequency // string isn't a palindrome return 0; } i = 0; // All odd appearing characters can also contribute to // the even length palindrome if one character // is removed from the frequency leaving it as even while (i < oddFreq.size()) { // If k palindromes are possible where k // is the number of characters with odd frequency if ((sumEven / 2) % oddFreq.size() == 0) return oddFreq.size(); // Current character can no longer be an element // in a string other than the mid character if (oddFreq[i] == 1) { i++; continue ; } // If current character has odd frequency > 1 // take two characters which can be used in // any of the parts sumEven += 2; // Update the frequency oddFreq[i] = oddFreq[i] - 2; } // If not possible, then every character of the // string will act as a separate palindrome return n; } // Driver code int main() { string s = "noonpeep" ; cout<<countMinParts(s); } |
Java
// Java implementation of the approach import java.util.*; public class GFG { // Function to return the frequency array // for the given string static int [] getFrequencies(String str) { int freq[] = new int [ 26 ]; for ( int i = 0 ; i < str.length(); i++) { freq[str.charAt(i) - 'a' ]++; } return freq; } // Function to return the required count static int countMinParts(String str) { int n = str.length(); int freq[] = getFrequencies(str); List<Integer> oddFreq = new ArrayList<>(); List<Integer> evenFreq = new ArrayList<>(); int i, sumEven = 0 ; for (i = 0 ; i < 26 ; i++) { if (freq[i] == 0 ) continue ; // Add frequencies of the even appearing // characters if (freq[i] % 2 == 0 ) evenFreq.add(freq[i]); // Count of the characters that appeared // odd number of times else oddFreq.add(freq[i]); } for (i = 0 ; i < evenFreq.size(); i++) { sumEven += evenFreq.get(i); } // If there are no characters with odd frequency if (oddFreq.size() == 0 ) return 1 ; // If there are no characters with even frequency if (sumEven == 0 ) { // Only a single character with odd frequency if (oddFreq.size() == 1 ) return 1 ; // More than 1 character with odd frequency // string isn't a palindrome return 0 ; } i = 0 ; // All odd appearing characters can also contribute to // the even length palindrome if one character // is removed from the frequency leaving it as even while (i < oddFreq.size()) { // If k palindromes are possible where k // is the number of characters with odd frequency if ((sumEven / 2 ) % oddFreq.size() == 0 ) return oddFreq.size(); // Current character can no longer be an element // in a string other than the mid character if (oddFreq.get(i) == 1 ) { i++; continue ; } // If current character has odd frequency > 1 // take two characters which can be used in // any of the parts sumEven += 2 ; // Update the frequency oddFreq.set(i, oddFreq.get(i) - 2 ); } // If not possible, then every character of the // string will act as a separate palindrome return n; } // Driver code public static void main(String[] args) { String s = "noonpeep" ; System.out.println(countMinParts(s)); } } // This code is contributed by chitranayal |
Python3
# Python3 implementation of the approach # Function to return the frequency array # for the given string def getFrequencies(string) : freq = [ 0 ] * 26 for i in range ( len (string)) : freq[ ord (string[i]) - ord ( 'a' )] + = 1 return freq # Function to return the required count def countMinParts(string) : n = len (string) freq = getFrequencies(string) oddFreq = [] evenFreq = [] sumEven = 0 for i in range ( 26 ) : if freq[i] = = 0 : continue # Add frequencies of the even # appearing characters if freq[i] % 2 = = 0 : evenFreq.append(freq[i]) # Count of the characters that # appeared odd number of times else : oddFreq.append(freq[i]) for i in range ( len (evenFreq)) : sumEven + = evenFreq[i] # If there are no characters with # odd frequency if len (oddFreq) = = 0 : return 1 # If there are no characters with # even frequency if sumEven = = 0 : # Only a single character with # odd frequency if len (oddFreq) = = 1 : return 1 # More than 1 character with odd # frequency string isn't a palindrome return 0 i = 0 # All odd appearing characters can also # contribute to the even length palindrome # if one character is removed from the # frequency leaving it as even while (i < len (oddFreq)) : # If k palindromes are possible where # k is the number of characters with # odd frequency if ((sumEven / 2 ) % len (oddFreq) = = 0 ) : return len (oddFreq) # Current character can no longer be # an element in a string other than # the mid character if (oddFreq[i] = = 1 ) : i + = 1 continue # If current character has odd frequency > 1 # take two characters which can be used in # any of the parts sumEven + = 2 # Update the frequency oddFreq[i] = oddFreq[i] - 2 # If not possible, then every character of the # string will act as a separate palindrome return n # Driver code if __name__ = = "__main__" : s = "noonpeep" print (countMinParts(s)) # This code is contributed by Ryuga |
C#
// C# implementation of the approach using System; using System.Collections.Generic; class GFG { // Function to return the frequency array // for the given string static int [] getFrequencies(String str) { int []freq = new int [26]; for ( int i = 0; i < str.Length; i++) { freq[str[i] - 'a' ]++; } return freq; } // Function to return the required count static int countMinParts(String str) { int n = str.Length; int []freq = getFrequencies(str); List< int > oddFreq = new List< int >(); List< int > evenFreq = new List< int >(); int i, sumEven = 0; for (i = 0; i < 26; i++) { if (freq[i] == 0) continue ; // Add frequencies of the even appearing // characters if (freq[i] % 2 == 0) evenFreq.Add(freq[i]); // Count of the characters that appeared // odd number of times else oddFreq.Add(freq[i]); } for (i = 0; i < evenFreq.Count; i++) { sumEven += evenFreq[i]; } // If there are no characters with odd frequency if (oddFreq.Count == 0) return 1; // If there are no characters with even frequency if (sumEven == 0) { // Only a single character with odd frequency if (oddFreq.Count == 1) return 1; // More than 1 character with odd frequency // string isn't a palindrome return 0; } i = 0; // All odd appearing characters can also contribute to // the even length palindrome if one character // is removed from the frequency leaving it as even while (i < oddFreq.Count) { // If k palindromes are possible where k // is the number of characters with odd frequency if ((sumEven / 2) % oddFreq.Count == 0) return oddFreq.Count; // Current character can no longer be an element // in a string other than the mid character if (oddFreq[i] == 1) { i++; continue ; } // If current character has odd frequency > 1 // take two characters which can be used in // any of the parts sumEven += 2; // Update the frequency oddFreq.Insert(i, oddFreq[i] - 2); } // If not possible, then every character of the // string will act as a separate palindrome return n; } // Driver code public static void Main(String[] args) { String s = "noonpeep" ; Console.WriteLine(countMinParts(s)); } } // This code has been contributed by 29AjayKumar |
Javascript
<script> // Javascript implementation of the approach // Function to return the frequency array // for the given string function getFrequencies(str) { let freq = new Array(26); for (let i=0;i<26;i++) freq[i]=0; for (let i = 0; i < str.length; i++) { freq[str[i].charCodeAt(0) - 'a' .charCodeAt(0)]++; } return freq; } // Function to return the required count function countMinParts(str) { let n = str.length; let freq = getFrequencies(str); let oddFreq = []; let evenFreq = []; let i, sumEven = 0; for (i = 0; i < 26; i++) { if (freq[i] == 0) continue ; // Add frequencies of the even appearing // characters if (freq[i] % 2 == 0) evenFreq.push(freq[i]); // Count of the characters that appeared // odd number of times else oddFreq.push(freq[i]); } for (i = 0; i < evenFreq.length; i++) { sumEven += evenFreq[i]; } // If there are no characters with odd frequency if (oddFreq.length == 0) return 1; // If there are no characters with even frequency if (sumEven == 0) { // Only a single character with odd frequency if (oddFreq.length == 1) return 1; // More than 1 character with odd frequency // string isn't a palindrome return 0; } i = 0; // All odd appearing characters can also contribute to // the even length palindrome if one character // is removed from the frequency leaving it as even while (i < oddFreq.length) { // If k palindromes are possible where k // is the number of characters with odd frequency if ((sumEven / 2) % oddFreq.length == 0) return oddFreq.length; // Current character can no longer be an element // in a string other than the mid character if (oddFreq[i] == 1) { i++; continue ; } // If current character has odd frequency > 1 // take two characters which can be used in // any of the parts sumEven += 2; // Update the frequency oddFreq[i]= oddFreq[i] - 2; } // If not possible, then every character of the // string will act as a separate palindrome return n; } // Driver code let s = "noonpeep" ; document.write(countMinParts(s)); // This code is contributed by rag2127 </script> |
1
Time complexity: O(n) where n is the length of the given string
Auxiliary space: O(1)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!