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 sint 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 codeint 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 npimport 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 sfunction 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 Codelet s = "abaaa";document.write(palindromeSubStrs(s));// This code is contributed by code_hunt</script> |
5
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.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!
