Skip to content
Related Articles

Related Articles

Count All Palindrome Sub-Strings in a String | Set 1

View Discussion
Improve Article
Save Article
  • Difficulty Level : Hard
  • Last Updated : 06 Jul, 2022
View Discussion
Improve Article
Save Article

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++




// 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




// 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




# 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#




// 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 then 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
// 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 then 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
?>

Javascript




<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>

Output

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:

C++




#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;
}

Java




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

Python3




# 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

C#




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

Javascript




<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>

Output

4

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. 


My Personal Notes arrow_drop_up
Recommended Articles
Page :

Start Your Coding Journey Now!