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++ program to find palindromic substrings of a string #include <bits/stdc++.h> using namespace std;
// Returns total number of palindrome substring of // length greater than equal to 2 int CountPS( char str[], int n)
{ //to store the count of palindrome subarrays
int ans=0;
// P[i][j] = true if substring str[i..j] is palindrome,
// else false
bool P[n][n];
memset (P, false , sizeof (P));
// palindrome of single length
for ( int i = 0; i < n; i++){
P[i][i] = true ;
}
// Palindromes of length more than or equal to 2. We start with
// a gap of length 1 and fill the DP table in a way that
// gap between starting and ending indexes increases one
// by one by outer loop.
for ( int gap = 2; gap <=n; gap++) {
// Pick starting point for current gap
for ( int i = 0; i <= n-gap; i++) {
// Set ending point
int j = gap + i-1;
// check If current string is palindrome of length 2
if (i==j-1){
P[i][j]=(str[i]==str[j]);
} else {
//check if the current substring is palindrome of length more than 2
//if characters at index i,j are equal check for string in between them
//from i+1 to j-1 if it is palindrome or not
P[i][j]=(str[i]==str[j] && P[i+1][j-1]);
}
//if substring from index i to j is palindrome increase the count
if (P[i][j]){
ans++;
}
}
}
// return total palindromic substrings
return ans;
} // Driver code int main()
{ char str[] = "abaab" ;
int n = strlen (str);
cout << CountPS(str, n) << endl;
return 0;
} |
// Java program to find palindromic substrings of a string public class GFG {
// Returns total number of palindrome substring of
// length greater than equal to 2
static int CountPS( char str[], int n)
{
// create empty 2-D matrix that counts all
// palindrome substring. dp[i][j] stores counts of
// palindromic substrings in st[i..j]
int dp[][] = new int [n][n];
// P[i][j] = true if substring str[i..j] is
// palindrome, else false
boolean P[][] = new boolean [n][n];
// palindrome of single length
for ( int i = 0 ; i < n; i++)
P[i][i] = true ;
// palindrome of length 2
for ( int i = 0 ; i < n - 1 ; i++) {
if (str[i] == str[i + 1 ]) {
P[i][i + 1 ] = true ;
dp[i][i + 1 ] = 1 ;
}
}
// Palindromes of length more than 2. This loop is
// similar to Matrix Chain Multiplication. We start
// with a gap of length 2 and fill the DP table in a
// way that gap between starting and ending indexes
// increases one by one by outer loop.
for ( int gap = 2 ; gap < n; gap++) {
// Pick starting point for current gap
for ( int i = 0 ; i < n - gap; i++) {
// Set ending point
int j = gap + i;
// If current string is palindrome
if (str[i] == str[j] && P[i + 1 ][j - 1 ])
P[i][j] = true ;
// Add current palindrome substring ( + 1)
// and rest palindrome substring (dp[i][j-1]
// + dp[i+1][j]) remove common palindrome
// substrings (- dp[i+1][j-1])
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 total palindromic substrings
return dp[ 0 ][n - 1 ];
}
// Driver code
public static void main(String[] args)
{
String str = "abaab" ;
System.out.println(
CountPS(str.toCharArray(), str.length()));
}
} |
# Python3 program to find palindromic # substrings of a string # Returns total number of palindrome # substring of length greater than # equal to 2 def CountPS( str , n):
# create empty 2-D matrix that counts
# all palindrome substring. dp[i][j]
# stores counts of palindromic
# substrings in st[i..j]
dp = [[ 0 for x in range (n)]
for y in range (n)]
# P[i][j] = true if substring str[i..j]
# is palindrome, else false
P = [[ False for x in range (n)]
for y in range (n)]
# palindrome of single length
for i in range (n):
P[i][i] = True
# palindrome of length 2
for i in range (n - 1 ):
if ( str [i] = = str [i + 1 ]):
P[i][i + 1 ] = True
dp[i][i + 1 ] = 1
# Palindromes of length more than 2. This
# loop is similar to Matrix Chain Multiplication.
# We start with a gap of length 2 and fill DP
# table in a way that the gap between starting and
# ending indexes increase one by one by
# outer loop.
for gap in range ( 2 , n):
# Pick a starting point for the current gap
for i in range (n - gap):
# Set ending point
j = gap + i
# If current string is palindrome
if ( str [i] = = str [j] and P[i + 1 ][j - 1 ]):
P[i][j] = True
# Add current palindrome substring ( + 1)
# and rest palindrome substring (dp[i][j-1] +
# dp[i+1][j]) remove common palindrome
# substrings (- dp[i+1][j-1])
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 total palindromic substrings
return dp[ 0 ][n - 1 ]
# Driver Code if __name__ = = "__main__" :
str = "abaab"
n = len ( str )
print (CountPS( str , n))
# This code is contributed by ita_c |
// C# program to find palindromic // substrings of a string using System;
class GFG {
// Returns total number of
// palindrome substring of
// length greater than equal to 2
public static int CountPS( char [] str, int n)
{
// create empty 2-D matrix that counts
// all palindrome substring. dp[i][j]
// stores counts of palindromic
// substrings in st[i..j]
int [][] dp
= RectangularArrays.ReturnRectangularIntArray(
n, n);
// P[i][j] = true if substring str[i..j]
// is palindrome, else false
bool [][] P
= RectangularArrays.ReturnRectangularBoolArray(
n, n);
// palindrome of single length
for ( int i = 0; i < n; i++) {
P[i][i] = true ;
}
// palindrome of length 2
for ( int i = 0; i < n - 1; i++) {
if (str[i] == str[i + 1]) {
P[i][i + 1] = true ;
dp[i][i + 1] = 1;
}
}
// Palindromes of length more than 2.
// This loop is similar to Matrix Chain
// Multiplication. We start with a gap
// of length 2 and fill DP table in a
// way that gap between starting and
// ending indexes increases one by one
// by outer loop.
for ( int gap = 2; gap < n; gap++) {
// Pick starting point for current gap
for ( int i = 0; i < n - gap; i++) {
// Set ending point
int j = gap + i;
// If current string is palindrome
if (str[i] == str[j] && P[i + 1][j - 1]) {
P[i][j] = true ;
}
// Add current palindrome substring
// ( + 1) and rest palindrome substring
// (dp[i][j-1] + dp[i+1][j]) remove common
// palindrome substrings (- dp[i+1][j-1])
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 total palindromic substrings
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;
}
}
// Driver Code
public static void Main( string [] args)
{
string str = "abaab" ;
Console.WriteLine(
CountPS(str.ToCharArray(), str.Length));
}
} // This code is contributed by Shrikant13 |
<?php // PHP program to find palindromic substrings // of a string // Returns total number of palindrome // substring of length greater than equal to 2 function CountPS( $str , $n )
{ // create empty 2-D matrix that counts
// all palindrome substring. dp[i][j]
// stores counts of palindromic
// substrings in st[i..j]
$dp = array ( array ());
for ( $i = 0; $i < $n ; $i ++)
for ( $j = 0; $j < $n ; $j ++)
$dp [ $i ][ $j ] = 0;
// P[i][j] = true if substring str[i..j]
// is palindrome, else false
$P = array ( array ());
for ( $i = 0; $i < $n ; $i ++)
for ( $j = 0; $j < $n ; $j ++)
$P [ $i ][ $j ] = false;
// palindrome of single length
for ( $i = 0; $i < $n ; $i ++)
$P [ $i ][ $i ] = true;
// palindrome of length 2
for ( $i = 0; $i < $n - 1; $i ++)
{
if ( $str [ $i ] == $str [ $i + 1])
{
$P [ $i ][ $i + 1] = true;
$dp [ $i ][ $i + 1] = 1;
}
}
// Palindromes of length more than 2. This
// loop is similar to Matrix Chain Multiplication.
// We start with a gap of length 2 and fill DP
// table in a way that gap between starting and
// ending indexes increases one by one by
// outer loop.
for ( $gap = 2; $gap < $n ; $gap ++)
{
// Pick starting point for current gap
for ( $i = 0; $i < $n - $gap ; $i ++)
{
// Set ending point
$j = $gap + $i ;
// If current string is palindrome
if ( $str [ $i ] == $str [ $j ] && $P [ $i + 1][ $j - 1])
$P [ $i ][ $j ] = true;
// Add current palindrome substring (+ 1)
// and rest palindrome substring (dp[i][j-1] +
// dp[i+1][j]) remove common palindrome
// substrings (- dp[i+1][j-1])
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 total palindromic substrings
return $dp [0][ $n - 1];
} // Driver Code $str = "abaab" ;
$n = strlen ( $str );
echo CountPS( $str , $n );
// This code is contributed by Ryuga ?> |
<script> // Javascript program to find palindromic substrings of a string // Returns total number of palindrome substring of
// length greater than equal to 2
function CountPS(str,n)
{
// create empty 2-D matrix that counts all
// palindrome substring. dp[i][j] stores counts of
// palindromic substrings in st[i..j]
let dp= new Array(n);
// P[i][j] = true if substring str[i..j] is
// palindrome, else false
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 ;
}
}
// palindrome of single length
for (let i = 0; i < n; i++)
P[i][i] = true ;
// palindrome of length 2
for (let i = 0; i < n - 1; i++) {
if (str[i] == str[i + 1]) {
P[i][i + 1] = true ;
dp[i][i + 1] = 1;
}
}
// Palindromes of length more than 2. This loop is
// similar to Matrix Chain Multiplication. We start
// with a gap of length 2 and fill the DP table in a
// way that gap between starting and ending indexes
// increases one by one by outer loop.
for (let gap = 2; gap < n; gap++) {
// Pick starting point for current gap
for (let i = 0; i < n - gap; i++) {
// Set ending point
let j = gap + i;
// If current string is palindrome
if (str[i] == str[j] && P[i + 1][j - 1])
P[i][j] = true ;
// Add current palindrome substring ( + 1)
// and rest palindrome substring (dp[i][j-1]
// + dp[i+1][j]) remove common palindrome
// substrings (- dp[i+1][j-1])
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 total palindromic substrings
return dp[0][n - 1];
}
// Driver code
let str = "abaab" ;
document.write(
CountPS(str.split( "" ), str.length));
// This code is contributed by avanitrachhadiya2155
</script> |
3
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:
#include <bits/stdc++.h> using namespace std;
int dp[1001][1001]; // 2D matrix
bool isPal(string s, int i, int j)
{ // Base condition
if (i > j)
return 1;
// check if the recursive tree
// for given i, j
// has already been executed
if (dp[i][j] != -1)
return dp[i][j];
// If first and last characters of
// substring are unequal
if (s[i] != s[j])
return dp[i][j] = 0;
// memoization
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;
// 2 for loops are required to check for
// all the palindromes in the string.
for ( int i = 0; i < n; i++)
{
for ( int j = i + 1; j < n; j++)
{
// Increment count for every palindrome
if (isPal(s, i, j))
count++;
}
}
// return total palindromic substrings
return count;
} // Driver code int main()
{ string s = "abbaeae" ;
cout << countSubstrings(s);
//"bb" , "abba" ,"aea", "eae" are
// the 4 palindromic substrings.
// This code is contributed by Bhavneet Singh
return 0;
} |
import java.util.*;
public class Main
{ static int dp[][] = new int [ 1001 ][ 1001 ]; // 2D matrix
public static int isPal(String s, int i, int j)
{
// Base condition
if (i > j)
return 1 ;
// check if the recursive tree
// for given i, j
// has already been executed
if (dp[i][j] != - 1 )
return dp[i][j];
// If first and last characters of
// substring are unequal
if (s.charAt(i) != s.charAt(j))
return dp[i][j] = 0 ;
// memoization
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 ;
// 2 for loops are required to check for
// all the palindromes in the string.
for ( int i = 0 ; i < n; i++)
{
for ( int j = i + 1 ; j < n; j++)
{
// Increment count for every palindrome
if (isPal(s, i, j) != 0 )
count++;
}
}
// return total palindromic substrings
return count;
}
public static void main(String[] args) {
String s = "abbaeae" ;
System.out.println(countSubstrings(s));
}
} // This code is contributed by divyeshrabadiya07 |
# 2D matrix dp = [[ - 1 for i in range ( 1001 )]
for j in range ( 1001 )]
def isPal(s, i, j):
# Base condition
if (i > j):
return 1
# Check if the recursive tree
# for given i, j
# has already been executed
if (dp[i][j] ! = - 1 ):
return dp[i][j]
# If first and last characters of
# substring are unequal
if (s[i] ! = s[j]):
dp[i][j] = 0
return dp[i][j]
# Memoization
dp[i][j] = isPal(s, i + 1 , j - 1 )
return dp[i][j]
def countSubstrings(s):
n = len (s)
count = 0
# 2 for loops are required to check for
# all the palindromes in the string.
for i in range (n):
for j in range (i + 1 , n):
# Increment count for every palindrome
if (isPal(s, i, j)):
count + = 1
# Return total palindromic substrings
return count
# Driver code s = "abbaeae"
print (countSubstrings(s))
# This code is contributed by rag2127 |
using System;
class GFG{
// 2D matrix static int [,] dp = new int [1001, 1001];
static int isPal( string s, int i, int j)
{ // Base condition
if (i > j)
return 1;
// Check if the recursive tree
// for given i, j
// has already been executed
if (dp[i, j] != -1)
return dp[i, j];
// If first and last characters of
// substring are unequal
if (s[i] != s[j])
return dp[i, j] = 0;
// Memoization
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;
// 2 for loops are required to check for
// all the palindromes in the string.
for ( int i = 0; i < n; i++)
{
for ( int j = i + 1; j < n; j++)
{
// Increment count for every palindrome
if (isPal(s, i, j) != 0)
count++;
}
}
// Return total palindromic substrings
return count;
} // Driver Code static void Main()
{ string s = "abbaeae" ;
Console.WriteLine(countSubstrings(s));
} } // This code is contributed by divyesh072019 |
<script> var dp = Array(1001).fill().map(()=>Array(1001).fill(-1)); // 2D matrix
function isPal( s , i , j)
{
// Base condition
if (i > j)
return 1;
// check if the recursive tree
// for given i, j
// has already been executed
if (dp[i][j] != -1)
return dp[i][j];
// If first and last characters of
// substring are unequal
if (s.charAt(i) != s.charAt(j))
return dp[i][j] = 0;
// memoization
return dp[i][j] = isPal(s, i + 1, j - 1);
}
function countSubstrings( s) {
var n = s.length;
var count = 0;
// 2 for loops are required to check for
// all the palindromes in the string.
for (i = 0; i < n; i++) {
for (j = i + 1; j < n; j++) {
// Increment count for every palindrome
if (isPal(s, i, j) != 0)
count++;
}
}
// return total palindromic substrings
return count;
}
// Driver code
var s = "abbaeae" ;
document.write(countSubstrings(s));
// This code is contributed by Rajput-Ji </script> |
4
Time Complexity: O(n3)
Auxiliary Space: O(n2)
Count All Palindrome Sub-Strings in a String | Set 2