Distinct palindromic sub-strings of the given string using Dynamic Programming
Given a string str of lowercase alphabets, the task is to find all distinct palindromic sub-strings of the given string.
Examples:
Input: str = “abaaa”
Output: 5
Palindromic sub-strings are “a”, “aa”, “aaa”, “aba” and “b”
Input: str = “abcd”
Output: 4
Approach: The solution to this problem has been discussed here using Manacher’s algorithm. However we can also solve it using dynamic programming.
Create an array dp[][] where dp[i][j] is set to 1 if str[i…j] is a palindrome else 0. After the array has been generated, store all the palindromic sub-strings in a map in order to get the count of distinct sub-strings.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int palindromeSubStrs(string s)
{
int dp[s.size()][s.size()];
int st, end, i, j, len;
map<string, bool > m;
for (i = 0; i < s.size(); i++) {
dp[i][i] = 1;
m[string(s.begin() + i, s.begin() + i + 1)] = 1;
}
for (i = 0; i < s.size() - 1; i++) {
if (s[i] == s[i + 1]) {
dp[i][i + 1] = 1;
m[string(s.begin() + i, s.begin() + i + 2)] = 1;
}
else {
dp[i][i + 1] = 0;
}
}
for (len = 3; len <= s.size(); len++) {
for (st = 0; st <= s.size() - len; st++) {
end = st + len - 1;
if (s[st] == s[end] && dp[st + 1][end - 1]) {
dp[st][end] = 1;
m[string(s.begin() + st, s.begin() + end + 1)] = 1;
}
else
dp[st][end] = 0;
}
}
return m.size();
}
int main()
{
string s = "abaaa" ;
cout << palindromeSubStrs(s);
return 0;
}
|
Java
import java.util.HashMap;
class GFG
{
static int palindromeSubStrs(String s)
{
int [][] dp = new int [s.length()][s.length()];
int st, end, i, len;
HashMap<String,
Boolean> m = new HashMap<>();
for (i = 0 ; i < s.length(); i++)
{
dp[i][i] = 1 ;
m.put(s.substring(i, i + 1 ), true );
}
for (i = 0 ; i < s.length() - 1 ; i++)
{
if (s.charAt(i) == s.charAt(i + 1 ))
{
dp[i][i + 1 ] = 1 ;
m.put(s.substring(i, i + 2 ), true );
}
else
dp[i][i + 1 ] = 0 ;
}
for (len = 3 ; len <= s.length(); len++)
{
for (st = 0 ; st <= s.length() - len; st++)
{
end = st + len - 1 ;
if (s.charAt(st) == s.charAt(end) &&
dp[st + 1 ][end - 1 ] == 1 )
{
dp[st][end] = 1 ;
m.put(s.substring(st, end + 1 ), true );
}
else
dp[st][end] = 0 ;
}
}
return m.size();
}
public static void main(String[] args)
{
String s = "abaaa" ;
System.out.println(palindromeSubStrs(s));
}
}
|
Python3
import numpy as np;
def palindromeSubStrs(s) :
dp = np.zeros(( len (s), len (s)));
m = {};
for i in range ( len (s)) :
dp[i][i] = 1 ;
m[s[i: i + 1 ]] = 1 ;
for i in range ( len (s) - 1 ) :
if (s[i] = = s[i + 1 ]) :
dp[i][i + 1 ] = 1 ;
m[ s[i : i + 2 ]] = 1 ;
else :
dp[i][i + 1 ] = 0 ;
for length in range ( 3 , len (s) + 1 ) :
for st in range ( len (s) - length + 1 ) :
end = st + length - 1 ;
if (s[st] = = s[end] and dp[st + 1 ][end - 1 ]) :
dp[st][end] = 1 ;
m[s[st : end + 1 ]] = 1 ;
else :
dp[st][end] = 0 ;
return len (m);
if __name__ = = "__main__" :
s = "abaaa" ;
print (palindromeSubStrs(s));
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static int palindromeSubStrs(String s)
{
int [,] dp = new int [s.Length, s.Length];
int st, end, i, len;
Dictionary<String,
Boolean> m = new Dictionary<String,
Boolean>();
for (i = 0; i < s.Length; i++)
{
dp[i,i] = 1;
if (!m.ContainsKey(s.Substring(i, 1)))
m.Add(s.Substring(i, 1), true );
}
for (i = 0; i < s.Length - 1; i++)
{
if (s[i] == s[i + 1])
{
dp[i, i + 1] = 1;
if (!m.ContainsKey(s.Substring(i, 2)))
m.Add(s.Substring(i, 2), true );
}
else
dp[i, i + 1] = 0;
}
for (len = 3; len <= s.Length; len++)
{
for (st = 0; st <= s.Length - len; st++)
{
end = st + len - 1;
if (s[st] == s[end] &&
dp[st + 1, end - 1] == 1)
{
dp[st, end] = 1;
m.Add(s.Substring(st, end + 1-st), true );
}
else
dp[st, end] = 0;
}
}
return m.Count;
}
public static void Main(String[] args)
{
String s = "abaaa" ;
Console.WriteLine(palindromeSubStrs(s));
}
}
|
Javascript
<script>
function palindromeSubStrs(s)
{
let dp = new Array(s.length);
for (let i = 0; i < dp.length; i++)
{
dp[i] = new Array(2);
}
for (let i = 0; i < dp.length; i++)
{
for (let j = 0; j < dp.length; j++)
{
dp[i][j] = 0;
}
}
let st, end, i, len;
let m = new Map();
for (i = 0; i < s.length; i++)
{
dp[i][i] = 1;
m.set(s.substr(i, i + 1), true );
}
for (i = 0; i < s.length - 1; i++)
{
if (s[i] == s[i + 1])
{
dp[i][i + 1] = 1;
m.set(s.substr(i, i + 2), true );
}
else
dp[i][i + 1] = 0;
}
for (len = 3; len <= s.length; len++)
{
for (st = 0; st <= s.length - len; st++)
{
end = st + len - 1;
if (s[st] == s[end] &&
dp[st + 1][end - 1] == 1)
{
dp[st][end] = 1;
m.set(s.substr(st, end + 1), true );
}
else
dp[st][end] = 0;
}
}
return m.size;
}
let s = "abaaa" ;
document.write(palindromeSubStrs(s));
</script>
|
Time complexity : O((n^2)logn), where n is the length of the input string. This is because we are using a nested loop to iterate over all possible substrings and check if they are palindromic.
Space complexity : O(n^2). This is because we are using a 2D array of size n x n to store the results of subproblems, and a map to store the distinct palindromic substrings.
Last Updated :
13 Jul, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...