All distinct palindromic sub-strings of a given string
Last Updated :
04 Aug, 2025
Given a string s of lowercase English letters. Find all the distinct continuous palindromic sub-strings which are present in the string s.
Examples:
Input: s = "abaaa"
Output: [ "a", "aa", "aaa", "aba", "b" ]
Explanation: All 5 distinct continuous palindromic sub-strings are listed above.
Input: s = "geek"
Output: [ "e", "ee", "g", "k" ]
Explanation: All 4 distinct continuous palindromic sub-strings are listed above.
[Naive Approach] Generating All Substrings - O(n^3 × log n)
The idea is to generate all possible substrings and find all the palindromic substrings, and use set to store all the distinct one.
C++
#include <iostream>
#include <string>
#include <vector>
#include <set>
using namespace std;
vector<string> palindromicSubstr(string &s) {
int n = s.length();
set<string> result;
// generate all substrings
for(int i = 0; i < n; i++) {
// to store the substring
string cur = "";
for(int j = i; j < n; j++) {
cur += s[j];
// check if cur is palindrome
int l = 0, r = cur.length() - 1;
bool isPalindrome = true;
while(l < r) {
if(cur[l] != cur[r]) {
isPalindrome = false;
break;
}
l++;
r--;
}
// if cur is palindrome, insert it into the set
if(isPalindrome) {
result.insert(cur);
}
}
}
// Convert the set to a vector
vector<string> res(result.begin(), result.end());
return res;
}
int main() {
string s = "abaaa";
vector<string> result = palindromicSubstr(s);
for(string s1 : result)
cout << s1 << " ";
return 0;
}
Java
import java.util.Set;
import java.util.ArrayList;
import java.util.TreeSet;
public class GfG {
public static ArrayList<String> palindromicSubstr(String s) {
int n = s.length();
// use TreeSet instead of HashSet to store sorted unique palindromic substrings
Set<String> result = new TreeSet<>();
// generate all substrings
for (int i = 0; i < n; i++) {
// to store the substring
String cur = "";
for (int j = i; j < n; j++) {
cur += s.charAt(j);
// check if cur is palindrome
int l = 0, r = cur.length() - 1;
boolean isPalindrome = true;
while (l < r) {
if (cur.charAt(l) != cur.charAt(r)) {
isPalindrome = false;
break;
}
l++;
r--;
}
// if cur is palindrome, insert it into the set
if (isPalindrome) {
result.add(cur);
}
}
}
// convert set to ArrayList
return new ArrayList<>(result);
}
public static void main(String[] args) {
String s = "abaaa";
ArrayList<String> result = palindromicSubstr(s);
for (String s1 : result)
System.out.print(s1 + " ");
}
}
Python
def palindromicSubstr(s):
n = len(s)
# use set to store sorted unique
# palindromic substrings
result = set()
# generate all substrings
for i in range(n):
# to store the substring
cur = ""
for j in range(i, n):
cur += s[j]
# check if cur is palindrome
l, r = 0, len(cur) - 1
is_palindrome = True
while l < r:
if cur[l] != cur[r]:
is_palindrome = False
break
l += 1
r -= 1
# if cur is palindrome, insert it into
# the set
if is_palindrome:
result.add(cur)
# convert set to sorted list
res = sorted(result)
return res
if __name__ == "__main__":
s = "abaaa"
result = palindromicSubstr(s)
for s1 in result:
print(s1, end=" ")
C#
using System;
using System.Collections.Generic;
class GfG {
public static List<string> palindromicSubstr(string s) {
int n = s.Length;
// use SortedSet to store sorted unique
// palindromic substrings
SortedSet<string> result =
new SortedSet<string>();
// generate all substrings
for (int i = 0; i < n; i++) {
// to store the substring
string cur = "";
for (int j = i; j < n; j++) {
cur += s[j];
// check if cur is palindrome
int l = 0, r = cur.Length - 1;
bool isPalindrome = true;
while (l < r) {
if (cur[l] != cur[r]) {
isPalindrome = false;
break;
}
l++;
r--;
}
// if cur is palindrome, insert it
// into the set
if (isPalindrome) {
result.Add(cur);
}
}
}
// convert set to list
return new List<string>(result);
}
static void Main() {
string s = "abaaa";
List<string> result = palindromicSubstr(s);
foreach (string s1 in result)
Console.Write(s1 + " ");
}
}
JavaScript
function palindromicSubstr(s) {
const n = s.length;
// use Set to store unique palindromic substrings
const result = new Set();
// generate all substrings
for (let i = 0; i < n; i++) {
// to store the substring
let cur = "";
for (let j = i; j < n; j++) {
cur += s[j];
// check if cur is palindrome
let l = 0, r = cur.length - 1;
let isPalindrome = true;
while (l < r) {
if (cur[l] !== cur[r]) {
isPalindrome = false;
break;
}
l++;
r--;
}
// if cur is palindrome, insert it into the set
if (isPalindrome) {
result.add(cur);
}
}
}
// convert set to sorted array
const res = Array.from(result).sort();
return res;
}
// Driver Code
const s = "abaaa";
const result = palindromicSubstr(s);
for (const s1 of result) {
process.stdout.write(s1 + " ");
}
[Better Approach] Using Rabin Karp and Center Expansion
The idea in this approach is to find all unique palindromic substrings in a given string using Rabin-Karp double hashing for fast substring comparison.
We expand around each character (odd length) and each pair (even length) to check for palindromes. For every palindrome found, we compute its double hash and store it in a set to ensure uniqueness.
We also mark its position using a 2D mark array. Finally, we extract all marked substrings and return them. This avoids using a set of strings and ensures efficient comparison using only integer hashes.
C++
#include <iostream>
#include <string>
#include <vector>
#include <set>
using namespace std;
class RabinKarpHash {
private:
const int mod1 = 1e9 + 7;
const int mod2 = 1e9 + 9;
const int base1 = 31;
const int base2 = 37;
vector<int> hash1, hash2;
vector<int> power1, power2;
// modular addition
int add(int a, int b, int mod) {
a += b;
if (a >= mod) a -= mod;
return a;
}
// modular subtraction
int sub(int a, int b, int mod) {
a -= b;
if (a < 0) a += mod;
return a;
}
// modular multiplication
int mul(int a, int b, int mod) {
return (int)((1LL * a * b) % mod);
}
// convert character to int
int charToInt(char c) {
return c - 'a' + 1;
}
public:
// constructor: precomputes both prefix hashes and powers
RabinKarpHash(string &s) {
int n = s.size();
hash1.resize(n);
hash2.resize(n);
power1.resize(n);
power2.resize(n);
hash1[0] = charToInt(s[0]);
hash2[0] = charToInt(s[0]);
power1[0] = 1;
power2[0] = 1;
for (int i = 1; i < n; ++i) {
hash1[i] = add(mul(hash1[i - 1], base1, mod1),
charToInt(s[i]), mod1);
power1[i] = mul(power1[i - 1], base1, mod1);
hash2[i] = add(mul(hash2[i - 1], base2, mod2),
charToInt(s[i]), mod2);
power2[i] = mul(power2[i - 1], base2, mod2);
}
}
// get double hash of substring s[l...r]
vector<int> getSubHash(int l, int r) {
int h1 = hash1[r];
int h2 = hash2[r];
if (l > 0) {
h1 = sub(h1, mul(hash1[l - 1], power1[r - l + 1], mod1), mod1);
h2 = sub(h2, mul(hash2[l - 1], power2[r - l + 1], mod2), mod2);
}
return {h1, h2};
}
};
vector<string> palindromicSubstr(string &s) {
RabinKarpHash rb(s);
int n = s.length();
// create a set to store the result
set<vector<int>> disPalin;
vector<vector<bool>> mark(n, vector<bool> (n, false));
// check for odd length palindromes
for (int i = 0; i < n; i++) {
int left = i, right = i;
while (left >= 0 && right < n && s[left] == s[right]) {
// add the palindrome substring
vector<int> hashleftright = rb.getSubHash(left, right);
if(disPalin.find(hashleftright) == disPalin.end()){
disPalin.insert(hashleftright);
mark[left][right] = true;
}
left--;
right++;
}
}
// check for even length palindromes
for (int i = 0; i < n - 1; i++) {
int left = i, right = i + 1;
while (left >= 0 && right < n && s[left] == s[right]) {
// add the palindrome substring
vector<int> hashleftright = rb.getSubHash(left, right);
if(disPalin.find(hashleftright) == disPalin.end()){
disPalin.insert(hashleftright);
mark[left][right] = true;
}
left--;
right++;
}
}
vector<string> res;
for(int i = 0; i < n ; i++){
string sub = "";
for(int j = i ; j < n ; j++){
sub.push_back(s[j]);
if(mark[i][j] == true){
res.push_back(sub);
}
}
}
return res;
}
int main() {
string s = "abaaa";
vector<string> result = palindromicSubstr(s);
for(string str : result)
cout << str << " ";
return 0;
}
Java
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
class RabinKarpHash {
private final int mod1 = (int)1e9 + 7;
private final int mod2 = (int)1e9 + 9;
private final int base1 = 31;
private final int base2 = 37;
private int[] hash1, hash2;
private int[] power1, power2;
// modular addition
int add(int a, int b, int mod) {
a += b;
if (a >= mod) a -= mod;
return a;
}
// modular subtraction
int sub(int a, int b, int mod) {
a -= b;
if (a < 0) a += mod;
return a;
}
// modular multiplication
int mul(int a, int b, int mod) {
return (int)(((long)a * b) % mod);
}
// convert character to int
int charToInt(char c) {
return c - 'a' + 1;
}
// constructor: precomputes both prefix hashes and powers
public RabinKarpHash(String s) {
int n = s.length();
hash1 = new int[n];
hash2 = new int[n];
power1 = new int[n];
power2 = new int[n];
hash1[0] = charToInt(s.charAt(0));
hash2[0] = charToInt(s.charAt(0));
power1[0] = 1;
power2[0] = 1;
for (int i = 1; i < n; ++i) {
hash1[i] = add(mul(hash1[i - 1], base1, mod1), charToInt(s.charAt(i)), mod1);
power1[i] = mul(power1[i - 1], base1, mod1);
hash2[i] = add(mul(hash2[i - 1], base2, mod2), charToInt(s.charAt(i)), mod2);
power2[i] = mul(power2[i - 1], base2, mod2);
}
}
// get double hash of substring s[l...r]
public List<Integer> getSubHash(int l, int r) {
int h1 = hash1[r];
int h2 = hash2[r];
if (l > 0) {
h1 = sub(h1, mul(hash1[l - 1], power1[r - l + 1], mod1), mod1);
h2 = sub(h2, mul(hash2[l - 1], power2[r - l + 1], mod2), mod2);
}
return Arrays.asList(h1, h2);
}
}
class GfG {
public static ArrayList<String> palindromicSubstr(String s) {
RabinKarpHash rb = new RabinKarpHash(s);
int n = s.length();
// create a set to store the result
Set<List<Integer>> disPalin = new HashSet<>();
boolean[][] mark = new boolean[n][n];
// check for odd length palindromes
for (int i = 0; i < n; i++) {
int left = i, right = i;
while (left >= 0 && right < n && s.charAt(left) == s.charAt(right)) {
// add the palindrome substring
List<Integer> hashleftright = rb.getSubHash(left, right);
if (!disPalin.contains(hashleftright)) {
disPalin.add(hashleftright);
mark[left][right] = true;
}
left--;
right++;
}
}
// check for even length palindromes
for (int i = 0; i < n - 1; i++) {
int left = i, right = i + 1;
while (left >= 0 && right < n && s.charAt(left) == s.charAt(right)) {
// add the palindrome substring
List<Integer> hashleftright = rb.getSubHash(left, right);
if (!disPalin.contains(hashleftright)) {
disPalin.add(hashleftright);
mark[left][right] = true;
}
left--;
right++;
}
}
ArrayList<String> res = new ArrayList<>();
for (int i = 0; i < n; i++) {
StringBuilder sub = new StringBuilder();
for (int j = i; j < n; j++) {
sub.append(s.charAt(j));
if (mark[i][j]) {
res.add(sub.toString());
}
}
}
return res;
}
public static void main(String[] args) {
String s = "abaaa";
ArrayList<String> result = palindromicSubstr(s);
for (String str : result) {
System.out.print(str + " ");
}
}
}
Python
# Rabin-Karp hash class
class RabinKarpHash:
def __init__(self, s):
self.mod1 = 10**9 + 7
self.mod2 = 10**9 + 9
self.base1 = 31
self.base2 = 37
n = len(s)
self.hash1 = [0] * n
self.hash2 = [0] * n
self.power1 = [0] * n
self.power2 = [0] * n
self.hash1[0] = self.charToInt(s[0])
self.hash2[0] = self.charToInt(s[0])
self.power1[0] = 1
self.power2[0] = 1
for i in range(1, n):
self.hash1[i] = self.add(self.mul(self.hash1[i-1], self.base1, self.mod1), \
self.charToInt(s[i]), self.mod1)
self.power1[i] = self.mul(self.power1[i-1], self.base1, self.mod1)
self.hash2[i] = self.add(self.mul(self.hash2[i-1], self.base2, self.mod2), \
self.charToInt(s[i]), self.mod2)
self.power2[i] = self.mul(self.power2[i-1], self.base2, self.mod2)
# modular addition
def add(self, a, b, mod):
a += b
if a >= mod:
a -= mod
return a
# modular subtraction
def sub(self, a, b, mod):
a -= b
if a < 0:
a += mod
return a
# modular multiplication
def mul(self, a, b, mod):
return (a * b) % mod
# convert character to int
def charToInt(self, c):
return ord(c) - ord('a') + 1
# get double hash of substring s[l...r]
def getSubHash(self, l, r):
h1 = self.hash1[r]
h2 = self.hash2[r]
if l > 0:
h1 = self.sub(h1, self.mul(self.hash1[l-1], \
self.power1[r-l+1], self.mod1), self.mod1)
h2 = self.sub(h2, self.mul(self.hash2[l-1], \
self.power2[r-l+1], self.mod2), self.mod2)
return (h1, h2)
# main logic
def palindromicSubstr(s):
rb = RabinKarpHash(s)
n = len(s)
# create a set to store the result
disPalin = set()
mark = [[False] * n for _ in range(n)]
# check for odd length palindromes
for i in range(n):
left = i
right = i
while left >= 0 and right < n and s[left] == s[right]:
hashleftright = rb.getSubHash(left, right)
if hashleftright not in disPalin:
disPalin.add(hashleftright)
mark[left][right] = True
left -= 1
right += 1
# check for even length palindromes
for i in range(n - 1):
left = i
right = i + 1
while left >= 0 and right < n and s[left] == s[right]:
hashleftright = rb.getSubHash(left, right)
if hashleftright not in disPalin:
disPalin.add(hashleftright)
mark[left][right] = True
left -= 1
right += 1
res = []
for i in range(n):
sub = ""
for j in range(i, n):
sub += s[j]
if mark[i][j]:
res.append(sub)
return res
if __name__ == "__main__":
s = "abaaa"
result = palindromicSubstr(s)
print(" ".join(result))
C#
using System;
using System.Collections.Generic;
class RabinKarpHash {
private readonly int mod1 = 1000000007;
private readonly int mod2 = 1000000009;
private readonly int base1 = 31;
private readonly int base2 = 37;
private List<int> hash1, hash2;
private List<int> power1, power2;
// modular addition
private int add(int a, int b, int mod) {
a += b;
if (a >= mod) a -= mod;
return a;
}
// modular subtraction
private int sub(int a, int b, int mod) {
a -= b;
if (a < 0) a += mod;
return a;
}
// modular multiplication
private int mul(int a, int b, int mod) {
return (int)(((long)a * b) % mod);
}
// convert character to int
private int charToInt(char c) {
return c - 'a' + 1;
}
// constructor: precomputes both prefix hashes and powers
public RabinKarpHash(string s) {
int n = s.Length;
hash1 = new List<int>(new int[n]);
hash2 = new List<int>(new int[n]);
power1 = new List<int>(new int[n]);
power2 = new List<int>(new int[n]);
hash1[0] = charToInt(s[0]);
hash2[0] = charToInt(s[0]);
power1[0] = 1;
power2[0] = 1;
for (int i = 1; i < n; ++i) {
hash1[i] = add(mul(hash1[i - 1], base1, mod1), charToInt(s[i]), mod1);
power1[i] = mul(power1[i - 1], base1, mod1);
hash2[i] = add(mul(hash2[i - 1], base2, mod2), charToInt(s[i]), mod2);
power2[i] = mul(power2[i - 1], base2, mod2);
}
}
// get double hash of substring s[l...r]
public Tuple<int, int> getSubHash(int l, int r) {
int h1 = hash1[r];
int h2 = hash2[r];
if (l > 0)
{
h1 = sub(h1, mul(hash1[l - 1], power1[r - l + 1], mod1), mod1);
h2 = sub(h2, mul(hash2[l - 1], power2[r - l + 1], mod2), mod2);
}
return Tuple.Create(h1, h2);
}
}
class GfG {
public static List<string> palindromicSubstr(string s) {
RabinKarpHash rb = new RabinKarpHash(s);
int n = s.Length;
// create a set to store the result
HashSet<string> disPalinSet = new HashSet<string>();
bool[,] mark = new bool[n, n];
// check for odd length palindromes
for (int i = 0; i < n; i++) {
int left = i, right = i;
while (left >= 0 && right < n && s[left] == s[right]) {
var hashleftright = rb.getSubHash(left, right);
string key = hashleftright.Item1 + "#" + hashleftright.Item2;
if (!disPalinSet.Contains(key))
{
disPalinSet.Add(key);
mark[left, right] = true;
}
left--;
right++;
}
}
// check for even length palindromes
for (int i = 0; i < n - 1; i++) {
int left = i, right = i + 1;
while (left >= 0 && right < n && s[left] == s[right]) {
var hashleftright = rb.getSubHash(left, right);
string key = hashleftright.Item1 + "#" + hashleftright.Item2;
if (!disPalinSet.Contains(key))
{
disPalinSet.Add(key);
mark[left, right] = true;
}
left--;
right++;
}
}
List<string> res = new List<string>();
for (int i = 0; i < n; i++) {
string sub = "";
for (int j = i; j < n; j++)
{
sub += s[j];
if (mark[i, j])
{
res.Add(sub);
}
}
}
return res;
}
// Driver Code
public static void Main() {
string s = "abaaa";
List<string> result = palindromicSubstr(s);
foreach (string str in result) {
Console.Write(str + " ");
}
}
}
JavaScript
function RabinKarpHash(s) {
this.mod1 = 1e9 + 7;
this.mod2 = 1e9 + 9;
this.base1 = 31;
this.base2 = 37;
this.hash1 = new Array(s.length).fill(0);
this.hash2 = new Array(s.length).fill(0);
this.power1 = new Array(s.length).fill(0);
this.power2 = new Array(s.length).fill(0);
const charToInt = c => c.charCodeAt(0) - 'a'.charCodeAt(0) + 1;
this.hash1[0] = charToInt(s[0]);
this.hash2[0] = charToInt(s[0]);
this.power1[0] = 1;
this.power2[0] = 1;
for (let i = 1; i < s.length; i++) {
this.hash1[i] = this.add(this.mul(this.hash1[i - 1], this.base1, this.mod1), charToInt(s[i]), this.mod1);
this.power1[i] = this.mul(this.power1[i - 1], this.base1, this.mod1);
this.hash2[i] = this.add(this.mul(this.hash2[i - 1], this.base2, this.mod2), charToInt(s[i]), this.mod2);
this.power2[i] = this.mul(this.power2[i - 1], this.base2, this.mod2);
}
}
RabinKarpHash.prototype.add = function(a, b, mod) {
a += b;
if (a >= mod) a -= mod;
return a;
};
RabinKarpHash.prototype.sub = function(a, b, mod) {
a -= b;
if (a < 0) a += mod;
return a;
};
RabinKarpHash.prototype.mul = function(a, b, mod) {
return ((a * b) % mod + mod) % mod;
};
RabinKarpHash.prototype.getSubHash = function(l, r) {
let h1 = this.hash1[r];
let h2 = this.hash2[r];
if (l > 0) {
h1 = this.sub(h1, this.mul(this.hash1[l - 1], this.power1[r - l + 1], this.mod1), this.mod1);
h2 = this.sub(h2, this.mul(this.hash2[l - 1], this.power2[r - l + 1], this.mod2), this.mod2);
}
return [h1, h2];
};
function palindromicSubstr(s) {
const n = s.length;
const mark = Array.from({ length: n }, () => Array(n).fill(false));
const disPalinSet = new Set();
const rk = new RabinKarpHash(s);
// check for odd length palindromes
for (let i = 0; i < n; i++) {
let left = i, right = i;
while (left >= 0 && right < n && s[left] === s[right]) {
const [h1, h2] = rk.getSubHash(left, right);
const key = `${h1}#${h2}`;
if (!disPalinSet.has(key)) {
disPalinSet.add(key);
mark[left][right] = true;
}
left--;
right++;
}
}
// check for even length palindromes
for (let i = 0; i < n - 1; i++) {
let left = i, right = i + 1;
while (left >= 0 && right < n && s[left] === s[right]) {
const [h1, h2] = rk.getSubHash(left, right);
const key = `${h1}#${h2}`;
if (!disPalinSet.has(key)) {
disPalinSet.add(key);
mark[left][right] = true;
}
left--;
right++;
}
}
const res = [];
for (let i = 0; i < n; i++) {
let sub = "";
for (let j = i; j < n; j++) {
sub += s[j];
if (mark[i][j]) {
res.push(sub);
}
}
}
return res;
}
// Driver Code
const s = "abaaa";
const result = palindromicSubstr(s);
console.log(result.join(" "));
Time Complexity: O(n² × log n), in the worst case, there can be O(n²) palindromic substrings, and each insertion into the set of hashes takes O(log n) time due to balanced BST structure, resulting in O(n² log n) total time.
Auxiliary Space: O(n²), we use a 2D mark array of size O(n²) and a set that may store up to O(n²) unique palindrome hashes, leading to overall O(n²) auxiliary space.
[Expected Approach] Using Dynamic Programming and KMP Algorithm - O(n^2) Time and O(n^2) Space
The idea is to identify all palindromic substrings in a given string using a dynamic programming method, then eliminate duplicates by leveraging the KMP algorithm, and finally print the distinct palindromes along with their count.
Follow the below given steps:
- First, for every possible substring, use dynamic programming to check if it is a palindrome.
- Next, for every index starting from 0, apply the KMP algorithm to compare prefixes and suffixes. If a substring is both a palindrome and its prefix matches its suffix, mark it (for example, by setting the corresponding dp value to false) so that duplicate occurrences are removed.
- Finally, iterate over all substrings and print those that remain marked as palindromic in the dp array; the number of such entries gives the total count of distinct palindromic substrings.
C++
#include <iostream>
#include <string>
#include <vector>
using namespace std;
vector<string> palindromicSubstr(string &s) {
int n = s.length();
// Create a 2D array
vector<vector<bool>> dp(n, vector<bool>(n, false));
for (int i = 0; i < n; i++) {
// base case every char is palindrome
dp[i][i] = 1;
// check for every substring of length 2
if (i < n && s[i] == s[i + 1]) {
dp[i][i + 1] = 1;
}
}
// check every substring of length
// greater than 2 for palindrome
for (int len = 3; len <= n; len++) {
for (int i = 0; i + len - 1 < n; i++) {
if (s[i] == s[i + (len - 1)]
&& dp[i + 1][i + (len - 1) - 1]) {
dp[i][i + (len - 1)] = true;
}
}
}
// create an array of size n
// to operate the kmp algorithm
vector<int> kmp(n, 0);
for (int i = 0; i < n; i++) {
// starting kmp for every i from 0 to n-1
int j = 0, k = 1;
while (k + i < n) {
if (s[j + i] == s[k + i]) {
// make suffix to be false,if this
// suffix is palindrome then
// it is included in prefix
dp[k + i - j][k + i] = false;
kmp[k++] = ++j;
}
else if (j > 0) {
j = kmp[j - 1];
}
else {
kmp[k++] = 0;
}
}
}
// Create an array to store the result
vector<string> result;
for (int i = 0; i < n; i++) {
// to store the current string
string cur;
for (int j = i; j < n; j++) {
cur += s[j];
if (dp[i][j]) {
result.push_back(cur);
}
}
}
return result;
}
int main() {
string s = "abaaa";
vector<string> result = palindromicSubstr(s);
for(string s : result)
cout << s << " ";
return 0;
}
Java
import java.util.ArrayList;
import java.util.Arrays;
class GfG {
static ArrayList<String> palindromicSubstr(String s) {
int n = s.length();
// Create a 2D array
boolean[][] dp = new boolean[n][n];
for (int i = 0; i < n; i++) {
// base case every char is palindrome
dp[i][i] = true;
// check for every substring of length 2
if (i < n - 1 && s.charAt(i) == s.charAt(i + 1)) {
dp[i][i + 1] = true;
}
}
// check every substring of length
// greater than 2 for palindrome
for (int len = 3; len <= n; len++) {
for (int i = 0; i + len - 1 < n; i++) {
if (s.charAt(i) == s.charAt(i + len - 1)
&& dp[i + 1][i + len - 2]) {
dp[i][i + len - 1] = true;
}
}
}
// create an array of size n
// to operate the kmp algorithm
int[] kmp = new int[n];
Arrays.fill(kmp, 0);
for (int i = 0; i < n; i++) {
// starting kmp for every i from 0 to n-1
int j = 0, k = 1;
while (k + i < n) {
if (s.charAt(j + i) == s.charAt(k + i)) {
// make suffix to be false, if this
// suffix is palindrome then
// it is included in prefix
dp[k + i - j][k + i] = false;
kmp[k++] = ++j;
}
else if (j > 0) {
j = kmp[j - 1];
}
else {
kmp[k++] = 0;
}
}
}
// Create an array to store the result
ArrayList<String> result = new ArrayList<>();
for (int i = 0; i < n; i++) {
// to store the current string
String cur = "";
for (int j = i; j < n; j++) {
cur += s.charAt(j);
if (dp[i][j]) {
result.add(cur);
}
}
}
return result;
}
public static void main(String[] args) {
String s = "abaaa";
ArrayList<String> result = palindromicSubstr(s);
for (String s1 : result)
System.out.print(s1 + " ");
}
}
Python
def palindromicSubstr(s):
n = len(s)
# Create a 2D array
dp = [[False for _ in range(n)] for _ in range(n)]
for i in range(n):
# base case every char is palindrome
dp[i][i] = True
# check for every substring of length 2
if i < n - 1 and s[i] == s[i + 1]:
dp[i][i + 1] = True
# check every substring of length
# greater than 2 for palindrome
for length in range(3, n + 1):
for i in range(n - length + 1):
j = i + length - 1
if s[i] == s[j] and dp[i + 1][j - 1]:
dp[i][j] = True
# create an array of size n
# to operate the kmp algorithm
kmp = [0] * n
for i in range(n):
# starting kmp for every i from 0 to n-1
j = 0
k = 1
while k + i < n:
if s[i + j] == s[i + k]:
# make suffix to be false, if this
# suffix is palindrome then
# it is included in prefix
dp[i + k - j][i + k] = False
kmp[k] = j + 1
j += 1
k += 1
elif j > 0:
j = kmp[j - 1]
else:
kmp[k] = 0
k += 1
# Create an array to store the result
result = []
for i in range(n):
# to store the current string
cur = ""
for j in range(i, n):
cur += s[j]
if dp[i][j]:
result.append(cur)
return result
if __name__ == "__main__":
s = "abaaa"
result = palindromicSubstr(s)
for s in result:
print(s, end=" ")
C#
using System;
using System.Collections.Generic;
class GfG {
static List<string> palindromicSubstr(ref string s) {
int n = s.Length;
// Create a 2D array
bool[,] dp = new bool[n, n];
for (int i = 0; i < n; i++) {
// base case every char is palindrome
dp[i, i] = true;
// check for every substring of length 2
if (i < n - 1 && s[i] == s[i + 1])
dp[i, i + 1] = true;
}
// check every substring of length
// greater than 2 for palindrome
for (int len = 3; len <= n; len++) {
for (int i = 0; i + len - 1 < n; i++) {
int j = i + len - 1;
if (s[i] == s[j] && dp[i + 1, j - 1])
dp[i, j] = true;
}
}
// create an array of size n
// to operate the kmp algorithm
int[] kmp = new int[n];
for (int i = 0; i < n; i++) {
kmp[i] = 0;
}
for (int i = 0; i < n; i++) {
// starting kmp for every i from 0 to n-1
int j = 0, k = 1;
while (k + i < n) {
if (s[i + j] == s[i + k]) {
// make suffix to be false, if this
// suffix is palindrome then
// it is included in prefix
dp[i + k - j, i + k] = false;
kmp[k] = ++j;
k++;
}
else if (j > 0) {
j = kmp[j - 1];
}
else {
kmp[k] = 0;
k++;
}
}
}
// Create an array to store the result
List<string> result = new List<string>();
for (int i = 0; i < n; i++) {
// to store the current string
string cur = "";
for (int j = i; j < n; j++) {
cur += s[j];
if (dp[i, j])
result.Add(cur);
}
}
return result;
}
static void Main() {
string s = "abaaa";
List<string> result = palindromicSubstr(ref s);
foreach (string ss in result)
Console.Write(ss + " ");
}
}
JavaScript
function palindromicSubstr(s) {
let n = s.length;
// Create a 2D array
let dp = new Array(n);
for (let i = 0; i < n; i++) {
dp[i] = new Array(n).fill(false);
}
for (let i = 0; i < n; i++) {
// base case every char is palindrome
dp[i][i] = true;
// check for every substring of length 2
if (i < n - 1 && s[i] === s[i + 1])
dp[i][i + 1] = true;
}
// check every substring of length
// greater than 2 for palindrome
for (let len = 3; len <= n; len++) {
for (let i = 0; i + len - 1 < n; i++) {
let j = i + len - 1;
if (s[i] === s[j] && dp[i + 1][j - 1])
dp[i][j] = true;
}
}
// create an array of size n
// to operate the kmp algorithm
let kmp = new Array(n).fill(0);
for (let i = 0; i < n; i++) {
// starting kmp for every i from 0 to n-1
let j = 0, k = 1;
while (k + i < n) {
if (s[i + j] === s[i + k]) {
// make suffix to be false, if this
// suffix is palindrome then
// it is included in prefix
dp[i + k - j][i + k] = false;
kmp[k] = ++j;
k++;
} else if (j > 0) {
j = kmp[j - 1];
} else {
kmp[k] = 0;
k++;
}
}
}
// Create an array to store the result
let result = [];
for (let i = 0; i < n; i++) {
// to store the current string
let cur = "";
for (let j = i; j < n; j++) {
cur += s[j];
if (dp[i][j])
result.push(cur);
}
}
return result;
}
// Driver Code
let s = "abaaa";
let result = palindromicSubstr(s);
console.log(result.join(" "));
Related Article:
Count All Palindrome Sub-Strings in a String
Explore
DSA Fundamentals
Data Structures
Algorithms
Advanced
Interview Preparation
Practice Problem