Count pairs of non-overlapping palindromic sub-strings of the given string
Given a string S. The task is to count the non-overlapping pairs of palindromic sub-strings S1 and S2 such that the strings should be S1[L1…R1] and S2[L2…R2] where 0 ? L1 ? R1 < L2 ? R2 < N. The task is to count the number of pairs of the non-overlapping palindromic sub-strings.
Examples:
Input: s = “aaa”
Output: 5
All possible pairs are (s[0], s[1]), (s[0], s[2]),
(s[0], s[1, 2]), (s[1], s[2]) and (s[0, 1], s[2])
Input: s = “abacaba”
Output: 36
Approach: We can use Dynamic Programming to solve the above problem. We can initially create the DP table which stores if substring[i….j] is palindrome or not. We maintain a boolean dp[n][n] that is filled in a bottom-up manner. The value of dp[i][j] is true if the substring is a palindrome, otherwise false. To calculate dp[i][j], we first check the value of dp[i+1][j-1], if the value is true and s[i] is same as s[j], then we make dp[i][j] true. Otherwise, the value of dp[i][j] is made false. The following steps can be followed thereafter to get the number of pairs.
- Create a left[] array, where left[i] stores the count of the number of palindromes to the left on the index i including i.
- Create a right[] array, where right[i] stores the count of the number of palindromes to the right on the index i including i.
- Iterate from 0 to length-1 and add left[i]*right[i+1]. The summation of it for every index will be the required number of pairs.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
#define N 100
void pre_process( bool dp[N][N], string s)
{
int n = s.size();
for ( int i = 0; i < n; i++) {
for ( int j = 0; j < n; j++)
dp[i][j] = false ;
}
for ( int j = 1; j <= n; j++) {
for ( int i = 0; i <= n - j; i++) {
if (j <= 2) {
if (s[i] == s[i + j - 1])
dp[i][i + j - 1] = true ;
}
else if (s[i] == s[i + j - 1])
dp[i][i + j - 1] = dp[i + 1][i + j - 2];
}
}
}
int countPairs(string s)
{
bool dp[N][N];
pre_process(dp, s);
int n = s.length();
int left[n];
memset (left, 0, sizeof left);
int right[n];
memset (right, 0, sizeof right);
left[0] = 1;
for ( int i = 1; i < n; i++) {
for ( int j = 0; j <= i; j++) {
if (dp[j][i] == 1)
left[i]++;
}
}
right[n - 1] = 1;
for ( int i = n - 2; i >= 0; i--) {
right[i] = right[i + 1];
for ( int j = n - 1; j >= i; j--) {
if (dp[i][j] == 1)
right[i]++;
}
}
int ans = 0;
for ( int i = 0; i < n - 1; i++)
ans += left[i] * right[i + 1];
return ans;
}
int main()
{
string s = "abacaba" ;
cout << countPairs(s);
return 0;
}
|
Java
class GFG
{
static int N = 100 ;
static void pre_process( boolean dp[][], char [] s)
{
int n = s.length;
for ( int i = 0 ; i < n; i++)
{
for ( int j = 0 ; j < n; j++)
{
dp[i][j] = false ;
}
}
for ( int j = 1 ; j <= n; j++)
{
for ( int i = 0 ; i <= n - j; i++)
{
if (j <= 2 )
{
if (s[i] == s[i + j - 1 ])
{
dp[i][i + j - 1 ] = true ;
}
}
else if (s[i] == s[i + j - 1 ])
{
dp[i][i + j - 1 ] = dp[i + 1 ][i + j - 2 ];
}
}
}
}
static int countPairs(String s)
{
boolean dp[][] = new boolean [N][N];
pre_process(dp, s.toCharArray());
int n = s.length();
int left[] = new int [n];
int right[] = new int [n];
left[ 0 ] = 1 ;
for ( int i = 1 ; i < n; i++)
{
for ( int j = 0 ; j <= i; j++)
{
if (dp[j][i] == true )
{
left[i]++;
}
}
}
right[n - 1 ] = 1 ;
for ( int i = n - 2 ; i >= 0 ; i--)
{
right[i] = right[i + 1 ];
for ( int j = n - 1 ; j >= i; j--)
{
if (dp[i][j] == true )
{
right[i]++;
}
}
}
int ans = 0 ;
for ( int i = 0 ; i < n - 1 ; i++)
{
ans += left[i] * right[i + 1 ];
}
return ans;
}
public static void main(String[] args)
{
String s = "abacaba" ;
System.out.println(countPairs(s));
}
}
|
Python3
N = 100
def pre_process(dp, s):
n = len (s)
for i in range (n):
for j in range (n):
dp[i][j] = False
for j in range ( 1 , n + 1 ):
for i in range (n - j + 1 ):
if (j < = 2 ):
if (s[i] = = s[i + j - 1 ]):
dp[i][i + j - 1 ] = True
elif (s[i] = = s[i + j - 1 ]):
dp[i][i + j - 1 ] = dp[i + 1 ][i + j - 2 ]
def countPairs(s):
dp = [[ False for i in range (N)]
for j in range (N)]
pre_process(dp, s)
n = len (s)
left = [ 0 for i in range (n)]
right = [ 0 for i in range (n)]
left[ 0 ] = 1
for i in range ( 1 , n):
for j in range (i + 1 ):
if (dp[j][i] = = 1 ):
left[i] + = 1
right[n - 1 ] = 1
for i in range (n - 2 , - 1 , - 1 ):
right[i] = right[i + 1 ]
for j in range (n - 1 , i - 1 , - 1 ):
if (dp[i][j] = = 1 ):
right[i] + = 1
ans = 0
for i in range (n - 1 ):
ans + = left[i] * right[i + 1 ]
return ans
s = "abacaba"
print (countPairs(s))
|
PHP
<?php
$N = 100;
function pre_process( $dp , $s )
{
$n = strlen ( $s );
for ( $i = 0; $i < $n ; $i ++)
{
for ( $j = 0; $j < $n ; $j ++)
$dp [ $i ][ $j ] = false;
}
for ( $j = 1; $j <= $n ; $j ++)
{
for ( $i = 0; $i <= $n - $j ; $i ++)
{
if ( $j <= 2)
{
if ( $s [ $i ] == $s [ $i + $j - 1])
$dp [ $i ][ $i + $j - 1] = true;
}
else if ( $s [ $i ] == $s [ $i + $j - 1])
$dp [ $i ][ $i + $j - 1] = $dp [ $i + 1][ $i + $j - 2];
}
}
return $dp ;
}
function countPairs( $s )
{
$dp = array ( array ());
$dp = pre_process( $dp , $s );
$n = strlen ( $s );
$left = array_fill (0, $n , 0);
$right = array_fill (0, $n , 0);
$left [0] = 1;
for ( $i = 1; $i < $n ; $i ++)
{
for ( $j = 0; $j <= $i ; $j ++)
{
if ( $dp [ $j ][ $i ] == 1)
$left [ $i ]++;
}
}
$right [ $n - 1] = 1;
for ( $i = $n - 2; $i >= 0; $i --)
{
$right [ $i ] = $right [ $i + 1];
for ( $j = $n - 1; $j >= $i ; $j --)
{
if ( $dp [ $i ][ $j ] == 1)
$right [ $i ]++;
}
}
$ans = 0;
for ( $i = 0; $i < $n - 1; $i ++)
$ans += $left [ $i ] * $right [ $i + 1];
return $ans ;
}
$s = "abacaba" ;
echo countPairs( $s );
?>
|
C#
using System;
class GFG
{
static int N = 100;
static void pre_process( bool [,]dp, char [] s)
{
int n = s.Length;
for ( int i = 0; i < n; i++)
{
for ( int j = 0; j < n; j++)
{
dp[i,j] = false ;
}
}
for ( int j = 1; j <= n; j++)
{
for ( int i = 0; i <= n - j; i++)
{
if (j <= 2)
{
if (s[i] == s[i + j - 1])
{
dp[i,i + j - 1] = true ;
}
}
else if (s[i] == s[i + j - 1])
{
dp[i,i + j - 1] = dp[i + 1,i + j - 2];
}
}
}
}
static int countPairs(String s)
{
bool [,]dp = new bool [N,N];
pre_process(dp, s.ToCharArray());
int n = s.Length;
int []left = new int [n];
int []right = new int [n];
left[0] = 1;
for ( int i = 1; i < n; i++)
{
for ( int j = 0; j <= i; j++)
{
if (dp[j,i] == true )
{
left[i]++;
}
}
}
right[n - 1] = 1;
for ( int i = n - 2; i >= 0; i--)
{
right[i] = right[i + 1];
for ( int j = n - 1; j >= i; j--)
{
if (dp[i,j] == true )
{
right[i]++;
}
}
}
int ans = 0;
for ( int i = 0; i < n - 1; i++)
{
ans += left[i] * right[i + 1];
}
return ans;
}
public static void Main(String[] args)
{
String s = "abacaba" ;
Console.Write(countPairs(s));
}
}
|
Javascript
<script>
var N = 100;
function pre_process( dp, s) {
var n = s.length;
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
dp[i][j] = false ;
}
}
for (j = 1; j <= n; j++) {
for (i = 0; i <= n - j; i++) {
if (j <= 2) {
if (s[i] == s[i + j - 1]) {
dp[i][i + j - 1] = true ;
}
}
else if (s[i] == s[i + j - 1]) {
dp[i][i + j - 1] = dp[i + 1][i + j - 2];
}
}
}
}
function countPairs(s) {
var dp = Array(N).fill().map(()=>Array(N).fill( false ));
pre_process(dp, s);
var n = s.length;
var left = Array(n).fill(0);
var right = Array(n).fill(0);
left[0] = 1;
for (i = 1; i < n; i++) {
for (j = 0; j <= i; j++) {
if (dp[j][i] == true ) {
left[i]++;
}
}
}
right[n - 1] = 1;
for (i = n - 2; i >= 0; i--) {
right[i] = right[i + 1];
for (j = n - 1; j >= i; j--) {
if (dp[i][j] == true ) {
right[i]++;
}
}
}
var ans = 0;
for (i = 0; i < n - 1; i++) {
ans += left[i] * right[i + 1];
}
return ans;
}
var s = "abacaba" ;
document.write(countPairs(s));
</script>
|
Time Complexity: O(N*N), as we are using nested loops for traversing N*N times. Where N is the length of the string.
Auxiliary Space: O(N*N), as we are using extra space for the dp matrix.
Last Updated :
21 Jun, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...