Split a string in equal parts such that all parts are palindromes
Last Updated :
19 Oct, 2022
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 length
Input: 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++
#include <bits/stdc++.h>
using namespace std;
int * getFrequencies(string str)
{
static int freq[26] = { 0 };
for ( int i = 0; i < str.length(); i++) {
freq[str[i] - 'a' ]++;
}
return freq;
}
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 ;
if (freq[i] % 2 == 0)
evenFreq.push_back(freq[i]);
else
oddFreq.push_back(freq[i]);
}
for (i = 0; i < evenFreq.size(); i++) {
sumEven += evenFreq[i];
}
if (oddFreq.size() == 0)
return 1;
if (sumEven == 0) {
if (oddFreq.size() == 1)
return 1;
return 0;
}
i = 0;
while (i < oddFreq.size()) {
if ((sumEven / 2) % oddFreq.size() == 0)
return oddFreq.size();
if (oddFreq[i] == 1) {
i++;
continue ;
}
sumEven += 2;
oddFreq[i] = oddFreq[i] - 2;
}
return n;
}
int main()
{
string s = "noonpeep" ;
cout<<countMinParts(s);
}
|
Java
import java.util.*;
public class GFG {
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;
}
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 ;
if (freq[i] % 2 == 0 )
evenFreq.add(freq[i]);
else
oddFreq.add(freq[i]);
}
for (i = 0 ; i < evenFreq.size(); i++) {
sumEven += evenFreq.get(i);
}
if (oddFreq.size() == 0 )
return 1 ;
if (sumEven == 0 ) {
if (oddFreq.size() == 1 )
return 1 ;
return 0 ;
}
i = 0 ;
while (i < oddFreq.size()) {
if ((sumEven / 2 ) % oddFreq.size() == 0 )
return oddFreq.size();
if (oddFreq.get(i) == 1 ) {
i++;
continue ;
}
sumEven += 2 ;
oddFreq.set(i, oddFreq.get(i) - 2 );
}
return n;
}
public static void main(String[] args)
{
String s = "noonpeep" ;
System.out.println(countMinParts(s));
}
}
|
Python3
def getFrequencies(string) :
freq = [ 0 ] * 26
for i in range ( len (string)) :
freq[ ord (string[i]) -
ord ( 'a' )] + = 1
return freq
def countMinParts(string) :
n = len (string)
freq = getFrequencies(string)
oddFreq = []
evenFreq = []
sumEven = 0
for i in range ( 26 ) :
if freq[i] = = 0 :
continue
if freq[i] % 2 = = 0 :
evenFreq.append(freq[i])
else :
oddFreq.append(freq[i])
for i in range ( len (evenFreq)) :
sumEven + = evenFreq[i]
if len (oddFreq) = = 0 :
return 1
if sumEven = = 0 :
if len (oddFreq) = = 1 :
return 1
return 0
i = 0
while (i < len (oddFreq)) :
if ((sumEven / 2 ) % len (oddFreq) = = 0 ) :
return len (oddFreq)
if (oddFreq[i] = = 1 ) :
i + = 1
continue
sumEven + = 2
oddFreq[i] = oddFreq[i] - 2
return n
if __name__ = = "__main__" :
s = "noonpeep"
print (countMinParts(s))
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static int [] getFrequencies(String str)
{
int []freq = new int [26];
for ( int i = 0; i < str.Length; i++)
{
freq[str[i] - 'a' ]++;
}
return freq;
}
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 ;
if (freq[i] % 2 == 0)
evenFreq.Add(freq[i]);
else
oddFreq.Add(freq[i]);
}
for (i = 0; i < evenFreq.Count; i++)
{
sumEven += evenFreq[i];
}
if (oddFreq.Count == 0)
return 1;
if (sumEven == 0)
{
if (oddFreq.Count == 1)
return 1;
return 0;
}
i = 0;
while (i < oddFreq.Count)
{
if ((sumEven / 2) % oddFreq.Count == 0)
return oddFreq.Count;
if (oddFreq[i] == 1)
{
i++;
continue ;
}
sumEven += 2;
oddFreq.Insert(i, oddFreq[i] - 2);
}
return n;
}
public static void Main(String[] args)
{
String s = "noonpeep" ;
Console.WriteLine(countMinParts(s));
}
}
|
Javascript
<script>
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 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 ;
if (freq[i] % 2 == 0)
evenFreq.push(freq[i]);
else
oddFreq.push(freq[i]);
}
for (i = 0; i < evenFreq.length; i++) {
sumEven += evenFreq[i];
}
if (oddFreq.length == 0)
return 1;
if (sumEven == 0) {
if (oddFreq.length == 1)
return 1;
return 0;
}
i = 0;
while (i < oddFreq.length) {
if ((sumEven / 2) % oddFreq.length == 0)
return oddFreq.length;
if (oddFreq[i] == 1) {
i++;
continue ;
}
sumEven += 2;
oddFreq[i]= oddFreq[i] - 2;
}
return n;
}
let s = "noonpeep" ;
document.write(countMinParts(s));
</script>
|
Time complexity: O(n) where n is the length of the given string
Auxiliary space: O(1)
Share your thoughts in the comments
Please Login to comment...