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.
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!