Find how many palindromic subsequences (need not necessarily be distinct) can be formed in a given string. Note that the empty string is not considered a palindrome.
Examples:
Input : str = "abcd"
Output : 4
Explanation :- palindromic subsequence are : "a" ,"b", "c" ,"d"
Input : str = "aab"
Output : 4
Explanation :- palindromic subsequence are :"a", "a", "b", "aa"
Input : str = "aaaa"
Output : 15
The above problem can be recursively defined.
Initial Values : i= 0, j= n-1;
CountPS(i,j)
// Every single character of a string is a palindrome
// subsequence
if i == j
return 1 // palindrome of length 1
// If first and last characters are same, then we
// consider it as palindrome subsequence and check
// for the rest subsequence (i+1, j), (i, j-1)
Else if (str[i] == str[j])
return countPS(i+1, j) + countPS(i, j-1) + 1;
else
// check for rest sub-sequence and remove common
// palindromic subsequences as they are counted
// twice when we do countPS(i+1, j) + countPS(i,j-1)
return countPS(i+1, j) + countPS(i, j-1) - countPS(i+1, j-1)

Recursive Approach
Here is the recursive code to the above approach
Java
public class GFG {
static int solve(String str, int i, int j)
{
if (i == j)
return 1 ;
if (i > j)
return 0 ;
if (str.charAt(i) == str.charAt(j)) {
return 1 + solve(str, i + 1 , j)
+ solve(str, i, j - 1 );
}
else
return solve(str, i + 1 , j)
+ solve(str, i, j - 1 )
- solve(str, i + 1 , j - 1 );
}
public static void main(String args[])
{
String str = "abcb" ;
System.out.println(
"Total palindromic "
+ "subsequence are : "
+ solve(str, 0 , str.length() - 1 ));
}
}
|
OutputTotal palindromic subsequence are : 6
If we draw recursion tree of the above recursive solution, we can observe overlapping Subproblems. Since the problem has overlapping subproblems, we can solve it efficiently using Dynamic Programming. Below is Dynamic Programming based solution.
C++
#include <cstring>
#include <iostream>
using namespace std;
int countPS(string str)
{
int N = str.length();
int cps[N + 1][N + 1];
memset (cps, 0, sizeof (cps));
for ( int i = 0; i < N; i++)
cps[i][i] = 1;
for ( int L = 2; L <= N; L++) {
for ( int i = 0; i <= N-L; i++) {
int k = L + i - 1;
if (str[i] == str[k])
cps[i][k]
= cps[i][k - 1] + cps[i + 1][k] + 1;
else
cps[i][k] = cps[i][k - 1] + cps[i + 1][k]
- cps[i + 1][k - 1];
}
}
return cps[0][N - 1];
}
int main()
{
string str = "abcb" ;
cout << "Total palindromic subsequence are : "
<< countPS(str) << endl;
return 0;
}
|
Java
public class GFG {
static int countPS(String str)
{
int N = str.length();
int [][] cps = new int [N][N];
for ( int i = 0 ; i < N; i++)
cps[i][i] = 1 ;
for ( int L = 2 ; L <= N; L++) {
for ( int i = 0 ; i <= N-L; i++) {
int k = L + i - 1 ;
if (str.charAt(i) == str.charAt(k)) {
cps[i][k] = cps[i][k - 1 ]
+ cps[i + 1 ][k] + 1 ;
} else {
cps[i][k] = cps[i][k - 1 ]
+ cps[i + 1 ][k]
- cps[i + 1 ][k - 1 ];
}
}
}
return cps[ 0 ][N - 1 ];
}
public static void main(String args[])
{
String str = "abcb" ;
System.out.println( "Total palindromic "
+ "subsequence are : "
+ countPS(str));
}
}
|
Python3
def countPS( str ):
N = len ( str )
cps = [[ 0 for i in range (N + 2 )] for j in range (N + 2 )]
for i in range (N):
cps[i][i] = 1
for L in range ( 2 , N + 1 ):
for i in range (N):
k = L + i - 1
if (k < N):
if ( str [i] = = str [k]):
cps[i][k] = (cps[i][k - 1 ] +
cps[i + 1 ][k] + 1 )
else :
cps[i][k] = (cps[i][k - 1 ] +
cps[i + 1 ][k] -
cps[i + 1 ][k - 1 ])
return cps[ 0 ][N - 1 ]
str = "abcb"
print ( "Total palindromic subsequence are : " , countPS( str ))
|
C#
using System;
class GFG {
static int countPS( string str)
{
int N = str.Length;
int [, ] cps = new int [N + 1, N + 1];
for ( int i = 0; i < N; i++)
cps[i, i] = 1;
for ( int L = 2; L <= N; L++) {
for ( int i = 0; i <= N-L; i++) {
int k = L + i - 1;
if (k < N) {
if (str[i] == str[k])
cps[i, k] = cps[i, k - 1]
+ cps[i + 1, k] + 1;
else
cps[i, k] = cps[i, k - 1]
+ cps[i + 1, k]
- cps[i + 1, k - 1];
}
}
}
return cps[0, N - 1];
}
public static void Main()
{
string str = "abcb" ;
Console.Write( "Total palindromic "
+ "subsequence are : "
+ countPS(str));
}
}
|
PHP
<?php
function countPS( $str )
{
$N = strlen ( $str );
$cps = array_fill (0, $N + 1,
array_fill (0, $N + 1, NULL));
for ( $i = 0; $i < $N ; $i ++)
$cps [ $i ][ $i ] = 1;
for ( $L = 2; $L <= $N ; $L ++)
{
for ( $i = 0; $i <= $N - $L ; $i ++)
{
$k = $L + $i - 1;
if ( $str [ $i ] == $str [ $k ])
$cps [ $i ][ $k ] = $cps [ $i ][ $k - 1] +
$cps [ $i + 1][ $k ] + 1;
else
$cps [ $i ][ $k ] = $cps [ $i ][ $k - 1] +
$cps [ $i + 1][ $k ] -
$cps [ $i + 1][ $k - 1];
}
}
return $cps [0][ $N - 1];
}
$str = "abcb" ;
echo "Total palindromic subsequence are : " .
countPS( $str ) . "\n" ;
?>
|
Javascript
<script>
function countPS(str)
{
let N = str.length;
let cps = new Array(N);
for (let i=0;i<N;i++)
{
cps[i]= new Array(N);
for (let j=0;j<N;j++)
{
cps[i][j]=0;
}
}
for (let i = 0; i < N; i++)
cps[i][i] = 1;
for (let L = 2; L <= N; L++) {
for (let i = 0; i <= N-L; i++) {
let k = L + i - 1;
if (str[i] == str[k]) {
cps[i][k] = cps[i][k - 1]
+ cps[i + 1][k] + 1;
} else {
cps[i][k] = cps[i][k - 1]
+ cps[i + 1][k]
- cps[i + 1][k - 1];
}
}
}
return cps[0][N - 1];
}
let str = "abcb" ;
document.write( "Total palindromic "
+ "subsequence are : "
+ countPS(str));
</script>
|
OutputTotal palindromic subsequence are : 6
Time Complexity: O(N2)
Auxiliary Space: O(N2)
Another approach: (Using memoization)
C++
#include <bits/stdc++.h>
using namespace std;
int n, dp[1000][1000];
string str = "abcb" ;
int countPS( int i, int j)
{
if (i > j)
return 0;
if (dp[i][j] != -1)
return dp[i][j];
if (i == j)
return dp[i][j] = 1;
else if (str[i] == str[j])
return dp[i][j]
= countPS(i + 1, j) +
countPS(i, j - 1) + 1;
else
return dp[i][j] = countPS(i + 1, j) +
countPS(i, j - 1) -
countPS(i + 1, j - 1);
}
int main()
{
memset (dp, -1, sizeof (dp));
n = str.size();
cout << "Total palindromic subsequence are : "
<< countPS(0, n - 1) << endl;
return 0;
}
|
Java
class GFG {
static int n;
static int [][] dp = new int [ 1000 ][ 1000 ];
static String str = "abcb" ;
static int countPS( int i, int j)
{
if (i > j)
return 0 ;
if (dp[i][j] != - 1 )
return dp[i][j];
if (i == j)
return dp[i][j] = 1 ;
else if (str.charAt(i) == str.charAt(j))
return dp[i][j]
= countPS(i + 1 , j) +
countPS(i, j - 1 ) + 1 ;
else
return dp[i][j] = countPS(i + 1 , j) +
countPS(i, j - 1 ) -
countPS(i + 1 , j - 1 );
}
public static void main(String[] args)
{
for ( int i = 0 ; i < 1000 ; i++)
for ( int j = 0 ; j < 1000 ; j++)
dp[i][j] = - 1 ;
n = str.length();
System.out.println( "Total palindromic subsequence"
+ "are : " + countPS( 0 , n - 1 ));
}
}
|
Python 3
str = "abcb"
def countPS(i, j):
if (i > j):
return 0
if (dp[i][j] ! = - 1 ):
return dp[i][j]
if (i = = j):
dp[i][j] = 1
return dp[i][j]
else if ( str [i] = = str [j]):
dp[i][j] = (countPS(i + 1 , j) +
countPS(i, j - 1 ) + 1 )
return dp[i][j]
else :
dp[i][j] = (countPS(i + 1 , j) +
countPS(i, j - 1 ) -
countPS(i + 1 , j - 1 ))
return dp[i][j]
if __name__ = = "__main__" :
dp = [[ - 1 for x in range ( 1000 )]
for y in range ( 1000 )]
n = len ( str )
print ( "Total palindromic subsequence are :" ,
countPS( 0 , n - 1 ))
|
C#
using System;
class GFG {
static int n;
static int [, ] dp = new int [1000, 1000];
static string str = "abcb" ;
static int countPS( int i, int j)
{
if (i > j)
return 0;
if (dp[i, j] != -1)
return dp[i, j];
if (i == j)
return dp[i, j] = 1;
else if (str[i] == str[j])
return dp[i, j]
= countPS(i + 1, j) +
countPS(i, j - 1) + 1;
else
return dp[i, j] = countPS(i + 1, j)
+ countPS(i, j - 1)
- countPS(i + 1, j - 1);
}
static void Main()
{
for ( int i = 0; i < 1000; i++)
for ( int j = 0; j < 1000; j++)
dp[i, j] = -1;
n = str.Length;
Console.Write( "Total palindromic subsequence"
+ "are : " + countPS(0, n - 1));
}
}
|
PHP
<?php
$dp = array_fill (0, 100,
array_fill (0, 1000, -1));
$str = "abcb" ;
$n = strlen ( $str );
function countPS( $i , $j )
{
global $str , $dp , $n ;
if ( $i > $j )
return 0;
if ( $dp [ $i ][ $j ] != -1)
return $dp [ $i ][ $j ];
if ( $i == $j )
return $dp [ $i ][ $j ] = 1;
else if ( $str [ $i ] == $str [ $j ])
return $dp [ $i ][ $j ] = countPS( $i + 1, $j ) +
countPS( $i , $j - 1) + 1;
else
return $dp [ $i ][ $j ] = countPS( $i + 1, $j ) +
countPS( $i , $j - 1) -
countPS( $i + 1, $j - 1);
}
echo "Total palindromic subsequence are : " .
countPS(0, $n - 1);
?>
|
Javascript
<script>
let n;
let dp= new Array(1000);
for (let i=0;i<1000;i++)
{
dp[i]= new Array(1000);
for (let j=0;j<1000;j++)
{
dp[i][j]=-1;
}
}
let str = "abcb" ;
function countPS(i,j)
{
if (i > j)
return 0;
if (dp[i][j] != -1)
return dp[i][j];
if (i == j)
return dp[i][j] = 1;
else if (str[i] == str[j])
return dp[i][j]
= countPS(i + 1, j) +
countPS(i, j - 1) + 1;
else
return dp[i][j] = countPS(i + 1, j) +
countPS(i, j - 1) -
countPS(i + 1, j - 1);
}
n = str.length;
document.write( "Total palindromic subsequence"
+ "are : " + countPS(0, n - 1));
</script>
|
OutputTotal palindromic subsequence are : 6
Time Complexity : O(N2),
Auxiliary Space: O(N2)
This article is contributed by Aarti_Rathi and Nishant_sing. 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.
Please write comments if you find anything incorrect, or if you want to share more information about the topic discussed above.