Open In App

All distinct palindromic sub-strings of a given string

Last Updated : 04 Aug, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

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 + " ");
}

Output
a aaa aba b aa 

[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(" "));

Output
a aba b aa aaa 

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(" "));

Output
a aba b aa aaa 

Related Article: 
Count All Palindrome Sub-Strings in a String


Similar Reads