Distinct palindromic sub-strings of the given string using Dynamic Programming
Last Updated :
13 Jul, 2023
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++
// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
// Function to return the count
// of distinct palindromic sub-strings
// of the given string s
int palindromeSubStrs(string s)
{
// To store the positions of
// palindromic sub-strings
int dp[s.size()][s.size()];
int st, end, i, j, len;
// Map to store the sub-strings
map<string, bool> m;
for (i = 0; i < s.size(); i++) {
// Sub-strings of length 1 are palindromes
dp[i][i] = 1;
// Store continuous palindromic sub-strings
m[string(s.begin() + i, s.begin() + i + 1)] = 1;
}
// Store palindromes of size 2
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;
}
// If str[i...(i+1)] is not a palindromic
// then set dp[i][i + 1] = 0
else {
dp[i][i + 1] = 0;
}
}
// Find palindromic sub-strings of length>=3
for (len = 3; len <= s.size(); len++) {
for (st = 0; st <= s.size() - len; st++) {
// End of palindromic substring
end = st + len - 1;
// If s[start] == s[end] and
// dp[start+1][end-1] is already palindrome
// then s[start....end] is also a palindrome
if (s[st] == s[end] && dp[st + 1][end - 1]) {
// Set dp[start][end] = 1
dp[st][end] = 1;
m[string(s.begin() + st, s.begin() + end + 1)] = 1;
}
// Not a palindrome
else
dp[st][end] = 0;
}
}
// Return the count of distinct palindromes
return m.size();
}
// Driver code
int main()
{
string s = "abaaa";
cout << palindromeSubStrs(s);
return 0;
}
Java
// Java implementation of the approach
import java.util.HashMap;
class GFG
{
// Function to return the count
// of distinct palindromic sub-strings
// of the given string s
static int palindromeSubStrs(String s)
{
// To store the positions of
// palindromic sub-strings
int[][] dp = new int[s.length()][s.length()];
int st, end, i, len;
// Map to store the sub-strings
HashMap<String,
Boolean> m = new HashMap<>();
for (i = 0; i < s.length(); i++)
{
// Sub-strings of length 1 are palindromes
dp[i][i] = 1;
// Store continuous palindromic sub-strings
m.put(s.substring(i, i + 1), true);
}
// Store palindromes of size 2
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);
}
// If str[i...(i+1)] is not a palindromic
// then set dp[i][i + 1] = 0
else
dp[i][i + 1] = 0;
}
// Find palindromic sub-strings of length>=3
for (len = 3; len <= s.length(); len++)
{
for (st = 0; st <= s.length() - len; st++)
{
// End of palindromic substring
end = st + len - 1;
// If s[start] == s[end] and
// dp[start+1][end-1] is already palindrome
// then s[start....end] is also a palindrome
if (s.charAt(st) == s.charAt(end) &&
dp[st + 1][end - 1] == 1)
{
// Set dp[start][end] = 1
dp[st][end] = 1;
m.put(s.substring(st, end + 1), true);
}
// Not a palindrome
else
dp[st][end] = 0;
}
}
// Return the count of distinct palindromes
return m.size();
}
// Driver Code
public static void main(String[] args)
{
String s = "abaaa";
System.out.println(palindromeSubStrs(s));
}
}
// This code is contributed by
// sanjeev2552
Python3
# Python3 implementation of the approach
# import numpy lib as np
import numpy as np;
# Function to return the count
# of distinct palindromic sub-strings
# of the given string s
def palindromeSubStrs(s) :
# To store the positions of
# palindromic sub-strings
dp = np.zeros((len(s),len(s)));
# Map to store the sub-strings
m = {};
for i in range(len(s)) :
# Sub-strings of length 1 are palindromes
dp[i][i] = 1;
# Store continuous palindromic sub-strings
m[s[i: i + 1]] = 1;
# Store palindromes of size 2
for i in range(len(s)- 1) :
if (s[i] == s[i + 1]) :
dp[i][i + 1] = 1;
m[ s[i : i + 2]] = 1;
# If str[i...(i+1)] is not a palindromic
# then set dp[i][i + 1] = 0
else :
dp[i][i + 1] = 0;
# Find palindromic sub-strings of length>=3
for length in range(3,len(s) + 1) :
for st in range(len(s) - length + 1) :
# End of palindromic substring
end = st + length - 1;
# If s[start] == s[end] and
# dp[start+1][end-1] is already palindrome
# then s[start....end] is also a palindrome
if (s[st] == s[end] and dp[st + 1][end - 1]) :
# Set dp[start][end] = 1
dp[st][end] = 1;
m[s[st : end + 1]] = 1;
# Not a palindrome
else :
dp[st][end] = 0;
# Return the count of distinct palindromes
return len(m);
# Driver code
if __name__ == "__main__" :
s = "abaaa";
print(palindromeSubStrs(s));
# This code is contributed by AnkitRai01
C#
// C# implementation of the approach
using System;
using System.Collections.Generic;
class GFG
{
// Function to return the count
// of distinct palindromic sub-strings
// of the given string s
static int palindromeSubStrs(String s)
{
// To store the positions of
// palindromic sub-strings
int[,] dp = new int[s.Length, s.Length];
int st, end, i, len;
// Map to store the sub-strings
Dictionary<String,
Boolean> m = new Dictionary<String,
Boolean>();
for (i = 0; i < s.Length; i++)
{
// Sub-strings of length 1 are palindromes
dp[i,i] = 1;
// Store continuous palindromic sub-strings
if(!m.ContainsKey(s.Substring(i, 1)))
m.Add(s.Substring(i, 1), true);
}
// Store palindromes of size 2
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);
}
// If str[i...(i+1)] is not a palindromic
// then set dp[i,i + 1] = 0
else
dp[i, i + 1] = 0;
}
// Find palindromic sub-strings of length>=3
for (len = 3; len <= s.Length; len++)
{
for (st = 0; st <= s.Length - len; st++)
{
// End of palindromic substring
end = st + len - 1;
// If s[start] == s[end] and
// dp[start+1,end-1] is already palindrome
// then s[start....end] is also a palindrome
if (s[st] == s[end] &&
dp[st + 1, end - 1] == 1)
{
// Set dp[start,end] = 1
dp[st, end] = 1;
m.Add(s.Substring(st, end + 1-st), true);
}
// Not a palindrome
else
dp[st, end] = 0;
}
}
// Return the count of distinct palindromes
return m.Count;
}
// Driver Code
public static void Main(String[] args)
{
String s = "abaaa";
Console.WriteLine(palindromeSubStrs(s));
}
}
// This code is contributed by PrinciRaj1992
JavaScript
<script>
// Javascript implementation of the approach
// Function to return the count
// of distinct palindromic sub-strings
// of the given string s
function palindromeSubStrs(s)
{
// To store the positions of
// palindromic sub-strings
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;
// Map to store the sub-strings
let m = new Map();
for(i = 0; i < s.length; i++)
{
// Sub-strings of length 1 are palindromes
dp[i][i] = 1;
// Store continuous palindromic sub-strings
m.set(s.substr(i, i + 1), true);
}
// Store palindromes of size 2
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);
}
// If str[i...(i+1)] is not a palindromic
// then set dp[i][i + 1] = 0
else
dp[i][i + 1] = 0;
}
// Find palindromic sub-strings of length>=3
for(len = 3; len <= s.length; len++)
{
for(st = 0; st <= s.length - len; st++)
{
// End of palindromic substring
end = st + len - 1;
// If s[start] == s[end] and
// dp[start+1][end-1] is already palindrome
// then s[start....end] is also a palindrome
if (s[st] == s[end] &&
dp[st + 1][end - 1] == 1)
{
// Set dp[start][end] = 1
dp[st][end] = 1;
m.set(s.substr(st, end + 1), true);
}
// Not a palindrome
else
dp[st][end] = 0;
}
}
// Return the count of distinct palindromes
return m.size;
}
// Driver Code
let s = "abaaa";
document.write(palindromeSubStrs(s));
// This code is contributed by code_hunt
</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.
Similar Reads
All distinct palindromic sub-strings of a given string Given a string str of lowercase ASCII characters. The task is to find all the distinct continuous palindromic sub-strings which are present in the string str. Examples: Input: str = "abaaa"Output: [ "a", "aa", "aaa", "aba", "b" ]Explanation: All 5 distinct continuous palindromic sub-strings are list
15+ min read
Longest Palindromic Substring using Dynamic Programming Given a string s, the task is to find the longest substring which is a palindrome. If there are multiple answers, then return the first occurrence of the longest palindromic substring from left to right.Examples:Input: s = "aaaabbaa"Output: "aabbaa"Explanation: The longest palindromic substring is "
7 min read
Rearrange the string to maximize the number of palindromic substrings Given a string S consisting of lowercase characters(a-z) only, the task is to print a new string by rearranging the string in such a way that maximizes the number of palindromic substrings. In case of multiple answers, print any one. Note: even if some substrings coincide, count them as many times a
5 min read
Permutation of given string that maximizes count of Palindromic substrings Given a string S, the task is to find the permutation of the string such that palindromic substrings in the string are maximum.Note: There can be multiple answers for each string. Examples: Input: S = "abcb" Output: "abbc" Explanation: "abbc" is the string with maximum number of palindromic substrin
3 min read
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:
13 min read