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)
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
04 Aug, 2022
Like Article
Save Article