Given a string, the task is to count all palindrome sub string in a given string. Length of palindrome sub string is greater than or equal to 2.
Examples:
Input : str = "abaab"
Output: 3
Explanation :
All palindrome substring are :
"aba" , "aa" , "baab"
Input : str = "abbaeae"
Output: 4
Explanation :
All palindrome substring are :
"bb" , "abba" ,"aea","eae"
We have discussed a similar problem below.
Find all distinct palindromic sub-strings of a given string
The above problem can be recursively defined.
Initial Values : i = 0, j = n-1;
Given string 'str'
CountPS(i, j)
// If length of string is 2 then we
// check both character are same or not
If (j == i+1)
return str[i] == str[j]
// this condition shows that in recursion if i crosses
// j then it will be a invalid substring or
// if i==j that means only one character is remaining
// and we require substring of length 2
//in both the conditions we need to return 0
Else if(i == j || i > j) return 0;
Else If str[i..j] is PALINDROME
// increment count by 1 and check for
// rest palindromic substring (i, j-1), (i+1, j)
// remove common palindrome substring (i+1, j-1)
return countPS(i+1, j) + countPS(i, j-1) + 1 -
countPS(i+1, j-1);
Else // if NOT PALINDROME
// We check for rest palindromic substrings (i, j-1)
// and (i+1, j)
// remove common palindrome substring (i+1 , j-1)
return countPS(i+1, j) + countPS(i, j-1) -
countPS(i+1 , j-1);
If we draw recursion tree of above recursive solution, we can observe overlapping Subproblems. Since the problem has overlapping sub-problems, we can solve it efficiently using Dynamic Programming.
Below is a Dynamic Programming based solution.
C++
#include <bits/stdc++.h>
using namespace std;
int CountPS( char str[], int n)
{
int ans=0;
bool P[n][n];
memset (P, false , sizeof (P));
for ( int i = 0; i < n; i++){
P[i][i] = true ;
}
for ( int gap = 2; gap <=n; gap++) {
for ( int i = 0; i <= n-gap; i++) {
int j = gap + i-1;
if (i==j-1){
P[i][j]=(str[i]==str[j]);
} else {
P[i][j]=(str[i]==str[j] && P[i+1][j-1]);
}
if (P[i][j]){
ans++;
}
}
}
return ans;
}
int main()
{
char str[] = "abaab" ;
int n = strlen (str);
cout << CountPS(str, n) << endl;
return 0;
}
|
Java
public class GFG {
static int CountPS( char str[], int n)
{
int dp[][] = new int [n][n];
boolean P[][] = new boolean [n][n];
for ( int i = 0 ; i < n; i++)
P[i][i] = true ;
for ( int i = 0 ; i < n - 1 ; i++) {
if (str[i] == str[i + 1 ]) {
P[i][i + 1 ] = true ;
dp[i][i + 1 ] = 1 ;
}
}
for ( int gap = 2 ; gap < n; gap++) {
for ( int i = 0 ; i < n - gap; i++) {
int j = gap + i;
if (str[i] == str[j] && P[i + 1 ][j - 1 ])
P[i][j] = true ;
if (P[i][j] == true )
dp[i][j] = dp[i][j - 1 ] + dp[i + 1 ][j]
+ 1 - dp[i + 1 ][j - 1 ];
else
dp[i][j] = dp[i][j - 1 ] + dp[i + 1 ][j]
- dp[i + 1 ][j - 1 ];
}
}
return dp[ 0 ][n - 1 ];
}
public static void main(String[] args)
{
String str = "abaab" ;
System.out.println(
CountPS(str.toCharArray(), str.length()));
}
}
|
Python3
def CountPS( str , n):
dp = [[ 0 for x in range (n)]
for y in range (n)]
P = [[ False for x in range (n)]
for y in range (n)]
for i in range (n):
P[i][i] = True
for i in range (n - 1 ):
if ( str [i] = = str [i + 1 ]):
P[i][i + 1 ] = True
dp[i][i + 1 ] = 1
for gap in range ( 2 , n):
for i in range (n - gap):
j = gap + i
if ( str [i] = = str [j] and P[i + 1 ][j - 1 ]):
P[i][j] = True
if (P[i][j] = = True ):
dp[i][j] = (dp[i][j - 1 ] +
dp[i + 1 ][j] + 1 - dp[i + 1 ][j - 1 ])
else :
dp[i][j] = (dp[i][j - 1 ] +
dp[i + 1 ][j] - dp[i + 1 ][j - 1 ])
return dp[ 0 ][n - 1 ]
if __name__ = = "__main__" :
str = "abaab"
n = len ( str )
print (CountPS( str , n))
|
C#
using System;
class GFG {
public static int CountPS( char [] str, int n)
{
int [][] dp
= RectangularArrays.ReturnRectangularIntArray(
n, n);
bool [][] P
= RectangularArrays.ReturnRectangularBoolArray(
n, n);
for ( int i = 0; i < n; i++) {
P[i][i] = true ;
}
for ( int i = 0; i < n - 1; i++) {
if (str[i] == str[i + 1]) {
P[i][i + 1] = true ;
dp[i][i + 1] = 1;
}
}
for ( int gap = 2; gap < n; gap++) {
for ( int i = 0; i < n - gap; i++) {
int j = gap + i;
if (str[i] == str[j] && P[i + 1][j - 1]) {
P[i][j] = true ;
}
if (P[i][j] == true ) {
dp[i][j] = dp[i][j - 1] + dp[i + 1][j]
+ 1 - dp[i + 1][j - 1];
}
else {
dp[i][j] = dp[i][j - 1] + dp[i + 1][j]
- dp[i + 1][j - 1];
}
}
}
return dp[0][n - 1];
}
public static class RectangularArrays {
public static int [][] ReturnRectangularIntArray(
int size1, int size2)
{
int [][] newArray = new int [size1][];
for ( int array1 = 0; array1 < size1; array1++) {
newArray[array1] = new int [size2];
}
return newArray;
}
public static bool [][] ReturnRectangularBoolArray(
int size1, int size2)
{
bool [][] newArray = new bool [size1][];
for ( int array1 = 0; array1 < size1; array1++) {
newArray[array1] = new bool [size2];
}
return newArray;
}
}
public static void Main( string [] args)
{
string str = "abaab" ;
Console.WriteLine(
CountPS(str.ToCharArray(), str.Length));
}
}
|
PHP
<?php
function CountPS( $str , $n )
{
$dp = array ( array ());
for ( $i = 0; $i < $n ; $i ++)
for ( $j = 0; $j < $n ; $j ++)
$dp [ $i ][ $j ] = 0;
$P = array ( array ());
for ( $i = 0; $i < $n ; $i ++)
for ( $j = 0; $j < $n ; $j ++)
$P [ $i ][ $j ] = false;
for ( $i = 0; $i < $n ; $i ++)
$P [ $i ][ $i ] = true;
for ( $i = 0; $i < $n - 1; $i ++)
{
if ( $str [ $i ] == $str [ $i + 1])
{
$P [ $i ][ $i + 1] = true;
$dp [ $i ][ $i + 1] = 1;
}
}
for ( $gap = 2; $gap < $n ; $gap ++)
{
for ( $i = 0; $i < $n - $gap ; $i ++)
{
$j = $gap + $i ;
if ( $str [ $i ] == $str [ $j ] && $P [ $i + 1][ $j - 1])
$P [ $i ][ $j ] = true;
if ( $P [ $i ][ $j ] == true)
$dp [ $i ][ $j ] = $dp [ $i ][ $j - 1] +
$dp [ $i + 1][ $j ] + 1 -
$dp [ $i + 1][ $j - 1];
else
$dp [ $i ][ $j ] = $dp [ $i ][ $j - 1] +
$dp [ $i + 1][ $j ] -
$dp [ $i + 1][ $j - 1];
}
}
return $dp [0][ $n - 1];
}
$str = "abaab" ;
$n = strlen ( $str );
echo CountPS( $str , $n );
?>
|
Javascript
<script>
function CountPS(str,n)
{
let dp= new Array(n);
let P= new Array(n);
for (let i=0;i<n;i++)
{
dp[i]= new Array(n);
P[i]= new Array(n);
for (let j=0;j<n;j++)
{
dp[i][j]=0;
P[i][j]= false ;
}
}
for (let i = 0; i < n; i++)
P[i][i] = true ;
for (let i = 0; i < n - 1; i++) {
if (str[i] == str[i + 1]) {
P[i][i + 1] = true ;
dp[i][i + 1] = 1;
}
}
for (let gap = 2; gap < n; gap++) {
for (let i = 0; i < n - gap; i++) {
let j = gap + i;
if (str[i] == str[j] && P[i + 1][j - 1])
P[i][j] = true ;
if (P[i][j] == true )
dp[i][j] = dp[i][j - 1] + dp[i + 1][j]
+ 1 - dp[i + 1][j - 1];
else
dp[i][j] = dp[i][j - 1] + dp[i + 1][j]
- dp[i + 1][j - 1];
}
}
return dp[0][n - 1];
}
let str = "abaab" ;
document.write(
CountPS(str.split( "" ), str.length));
</script>
|
Time Complexity: O(n2)
Auxiliary Space: O(n2)
Method 2: This approach uses Top Down DP i.e memoized version of recursion.
Recursive soln:
1. Here base condition comes out to be i>j if we hit this condition, return 1.
2. We check for each and every i and j, if the characters are equal,
if that is not the case, return 0.
3. Call the is_palindrome function again with incremented i and decremented j.
4. Check this for all values of i and j by applying 2 for loops.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
int dp[1001][1001];
bool isPal(string s, int i, int j)
{
if (i > j)
return 1;
if (dp[i][j] != -1)
return dp[i][j];
if (s[i] != s[j])
return dp[i][j] = 0;
return dp[i][j] = isPal(s, i + 1, j - 1);
}
int countSubstrings(string s)
{
memset (dp, -1, sizeof (dp));
int n = s.length();
int count = 0;
for ( int i = 0; i < n; i++)
{
for ( int j = i + 1; j < n; j++)
{
if (isPal(s, i, j))
count++;
}
}
return count;
}
int main()
{
string s = "abbaeae" ;
cout << countSubstrings(s);
return 0;
}
|
Java
import java.util.*;
public class Main
{
static int dp[][] = new int [ 1001 ][ 1001 ];
public static int isPal(String s, int i, int j)
{
if (i > j)
return 1 ;
if (dp[i][j] != - 1 )
return dp[i][j];
if (s.charAt(i) != s.charAt(j))
return dp[i][j] = 0 ;
return dp[i][j] = isPal(s, i + 1 , j - 1 );
}
public static int countSubstrings(String s)
{
for ( int [] row: dp)
{
Arrays.fill(row, - 1 );
}
int n = s.length();
int count = 0 ;
for ( int i = 0 ; i < n; i++)
{
for ( int j = i + 1 ; j < n; j++)
{
if (isPal(s, i, j) != 0 )
count++;
}
}
return count;
}
public static void main(String[] args) {
String s = "abbaeae" ;
System.out.println(countSubstrings(s));
}
}
|
Python3
dp = [[ - 1 for i in range ( 1001 )]
for j in range ( 1001 )]
def isPal(s, i, j):
if (i > j):
return 1
if (dp[i][j] ! = - 1 ):
return dp[i][j]
if (s[i] ! = s[j]):
dp[i][j] = 0
return dp[i][j]
dp[i][j] = isPal(s, i + 1 , j - 1 )
return dp[i][j]
def countSubstrings(s):
n = len (s)
count = 0
for i in range (n):
for j in range (i + 1 , n):
if (isPal(s, i, j)):
count + = 1
return count
s = "abbaeae"
print (countSubstrings(s))
|
C#
using System;
class GFG{
static int [,] dp = new int [1001, 1001];
static int isPal( string s, int i, int j)
{
if (i > j)
return 1;
if (dp[i, j] != -1)
return dp[i, j];
if (s[i] != s[j])
return dp[i, j] = 0;
return dp[i, j] = isPal(s, i + 1, j - 1);
}
static int countSubstrings( string s)
{
for ( int i = 0; i < 1001; i++)
{
for ( int j = 0; j < 1001; j++)
{
dp[i, j] = -1;
}
}
int n = s.Length;
int count = 0;
for ( int i = 0; i < n; i++)
{
for ( int j = i + 1; j < n; j++)
{
if (isPal(s, i, j) != 0)
count++;
}
}
return count;
}
static void Main()
{
string s = "abbaeae" ;
Console.WriteLine(countSubstrings(s));
}
}
|
Javascript
<script>
var dp = Array(1001).fill().map(()=>Array(1001).fill(-1));
function isPal( s , i , j)
{
if (i > j)
return 1;
if (dp[i][j] != -1)
return dp[i][j];
if (s.charAt(i) != s.charAt(j))
return dp[i][j] = 0;
return dp[i][j] = isPal(s, i + 1, j - 1);
}
function countSubstrings( s) {
var n = s.length;
var count = 0;
for (i = 0; i < n; i++) {
for (j = i + 1; j < n; j++) {
if (isPal(s, i, j) != 0)
count++;
}
}
return count;
}
var s = "abbaeae" ;
document.write(countSubstrings(s));
</script>
|
Time Complexity: O(n3)
Auxiliary Space: O(n2)
Count All Palindrome Sub-Strings in a String | Set 2
This article is contributed by Nishant_Singh(Pintu). If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.