Count special palindromes in a String
Given a String s, count all special palindromic substrings of size greater than 1. A Substring is called special palindromic substring if all the characters in the substring are same or only the middle character is different for odd length. Example “aabaa” and “aaa” are special palindromic substrings and “abcba” is not special palindromic substring.
Examples :
Input : str = " abab"
Output : 2
All Special Palindromic substring are: "aba", "bab"
Input : str = "aabbb"
Output : 4
All Special substring are: "aa", "bb", "bbb", "bb"
Simple Solution is that we simply generate all substrings one-by-one and count how many substring are Special Palindromic substring. This solution takes O(n3) time.
Efficient Solution
There are 2 Cases :
- Case 1: All Palindromic substrings have same character :
We can handle this case by simply counting the same continuous character and using formula K*(K+1)/2 (total number of substring possible : Here K is count of Continuous same char).
Lets Str = "aaabba"
Traverse string from left to right and Count of same char
"aaabba" = 3, 2, 1
for "aaa" : total substring possible are
'aa' 'aa', 'aaa', 'a', 'a', 'a' : 3(3+1)/2 = 6
"bb" : 'b', 'b', 'bb' : 2(2+1)/2 = 3
'a' : 'a' : 1(1+1)/2 = 1
- Case 2: We can handle this case by storing count of same character in another temporary array called “sameChar[n]” of size n. and pick each character one-by-one and check its previous and forward character are equal or not if equal then there are min_between( sameChar[previous], sameChar[forward] ) substring possible.
Let's Str = "aabaaab"
Count of smiler char from left to right :
that we will store in Temporary array "sameChar"
Str = " a a b a a a b "
sameChar[] = 2 2 1 3 3 3 1
According to the problem statement middle character is different:
so we have only left with char "b" at index :2 ( index from 0 to n-1)
substring : "aabaaa"
so only two substring are possible : "aabaa", "aba"
that is min (smilerChar[index-1], smilerChar[index+1] ) that is 2.
Below is the implementation of above idea
C++
#include <bits/stdc++.h>
using namespace std;
int CountSpecialPalindrome(string str)
{
int n = str.length();
int result = 0;
int sameChar[n] = { 0 };
int i = 0;
while (i < n) {
int sameCharCount = 1;
int j = i + 1;
while (str[i] == str[j] && j < n)
sameCharCount++, j++;
result += (sameCharCount * (sameCharCount + 1) / 2);
sameChar[i] = sameCharCount;
i = j;
}
for ( int j = 1; j < n; j++)
{
if (str[j] == str[j - 1])
sameChar[j] = sameChar[j - 1];
if (j > 0 && j < (n - 1) &&
(str[j - 1] == str[j + 1] &&
str[j] != str[j - 1]))
result += min(sameChar[j - 1],
sameChar[j + 1]);
}
return result - n;
}
int main()
{
string str = "abccba" ;
cout << CountSpecialPalindrome(str) << endl;
return 0;
}
|
Java
import java.io.*;
import java.util.*;
import java.lang.*;
class GFG
{
public static int CountSpecialPalindrome(String str)
{
int n = str.length();
int result = 0 ;
int [] sameChar = new int [n];
for ( int v = 0 ; v < n; v++)
sameChar[v] = 0 ;
int i = 0 ;
while (i < n)
{
int sameCharCount = 1 ;
int j = i + 1 ;
while (j < n &&
str.charAt(i) == str.charAt(j))
{
sameCharCount++;
j++;
}
result += (sameCharCount *
(sameCharCount + 1 ) / 2 );
sameChar[i] = sameCharCount;
i = j;
}
for ( int j = 1 ; j < n; j++)
{
if (str.charAt(j) == str.charAt(j - 1 ))
sameChar[j] = sameChar[j - 1 ];
if (j > 0 && j < (n - 1 ) &&
(str.charAt(j - 1 ) == str.charAt(j + 1 ) &&
str.charAt(j) != str.charAt(j - 1 )))
result += Math.min(sameChar[j - 1 ],
sameChar[j + 1 ]);
}
return result - n;
}
public static void main(String args[])
{
String str = "abccba" ;
System.out.print(CountSpecialPalindrome(str));
}
}
|
Python3
def CountSpecialPalindrome( str ):
n = len ( str );
result = 0 ;
sameChar = [ 0 ] * n;
i = 0 ;
while (i < n):
sameCharCount = 1 ;
j = i + 1 ;
while (j < n):
if ( str [i] ! = str [j]):
break ;
sameCharCount + = 1 ;
j + = 1 ;
result + = int (sameCharCount *
(sameCharCount + 1 ) / 2 );
sameChar[i] = sameCharCount;
i = j;
for j in range ( 1 , n):
if ( str [j] = = str [j - 1 ]):
sameChar[j] = sameChar[j - 1 ];
if (j > 0 and j < (n - 1 ) and
( str [j - 1 ] = = str [j + 1 ] and
str [j] ! = str [j - 1 ])):
result + = (sameChar[j - 1 ]
if (sameChar[j - 1 ] < sameChar[j + 1 ])
else sameChar[j + 1 ]);
return result - n;
str = "abccba" ;
print (CountSpecialPalindrome( str ));
|
C#
using System;
class GFG
{
public static int CountSpecialPalindrome(String str)
{
int n = str.Length;
int result = 0;
int [] sameChar = new int [n];
for ( int v = 0; v < n; v++)
sameChar[v] = 0;
int i = 0;
while (i < n)
{
int sameCharCount = 1;
int j = i + 1;
while (j < n &&
str[i] == str[j])
{
sameCharCount++;
j++;
}
result += (sameCharCount *
(sameCharCount + 1) / 2);
sameChar[i] = sameCharCount;
i = j;
}
for ( int j = 1; j < n; j++)
{
if (str[j] == str[j - 1])
sameChar[j] = sameChar[j - 1];
if (j > 0 && j < (n - 1) &&
(str[j - 1] == str[j + 1] &&
str[j] != str[j - 1]))
result += Math.Min(sameChar[j - 1],
sameChar[j + 1]);
}
return result - n;
}
public static void Main()
{
String str = "abccba" ;
Console.Write(CountSpecialPalindrome(str));
}
}
|
PHP
<?php
function CountSpecialPalindrome( $str )
{
$n = strlen ( $str );
$result = 0;
$sameChar = array_fill (0, $n , 0);
$i = 0;
while ( $i < $n )
{
$sameCharCount = 1;
$j = $i + 1;
while ( $j < $n )
{
if ( $str [ $i ] != $str [ $j ])
break ;
$sameCharCount ++;
$j ++;
}
$result += (int)( $sameCharCount *
( $sameCharCount + 1) / 2);
$sameChar [ $i ] = $sameCharCount ;
$i = $j ;
}
for ( $j = 1; $j < $n ; $j ++)
{
if ( $str [ $j ] == $str [ $j - 1])
$sameChar [ $j ] = $sameChar [ $j - 1];
if ( $j > 0 && $j < ( $n - 1) &&
( $str [ $j - 1] == $str [ $j + 1] &&
$str [ $j ] != $str [ $j - 1]))
$result += $sameChar [ $j - 1] <
$sameChar [ $j + 1] ?
$sameChar [ $j - 1] :
$sameChar [ $j + 1];
}
return $result - $n ;
}
$str = "abccba" ;
echo CountSpecialPalindrome( $str );
?>
|
Javascript
<script>
function CountSpecialPalindrome(str) {
var n = str.length;
var result = 0;
var sameChar = [...Array(n)];
var i = 0;
while (i < n) {
var sameCharCount = 1;
var j = i + 1;
while (str[i] == str[j] && j < n) sameCharCount++, j++;
result += (sameCharCount * (sameCharCount + 1)) / 2;
sameChar[i] = sameCharCount;
i = j;
}
for ( var j = 1; j < n; j++) {
if (str[j] == str[j - 1]) sameChar[j] = sameChar[j - 1];
if (
j > 0 &&
j < n - 1 &&
str[j - 1] == str[j + 1] &&
str[j] != str[j - 1]
)
result += Math.min(sameChar[j - 1], sameChar[j + 1]);
}
return result - n;
}
var str = "abccba" ;
document.write(CountSpecialPalindrome(str) + "<br>" );
</script>
|
Time Complexity : O(n)
Auxiliary Space : O(n)
Last Updated :
04 Aug, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...