Find all Palindromic Partitions of a String
Last Updated :
18 Jun, 2025
Given a string s, find all possible ways to partition it such that every substring in the partition is a palindrome.
Examples:
Input: s = "geeks"
Output: [[g, e, e, k, s], [g, ee, k, s]]
Explanation: [g, e, e, k, s] and [g, ee, k, s] are the only partitions of "geeks" where each substring is a palindrome.
Input: s = "abcba"
Output: [[a, b, c, b, a], [a, bcb, a], [abcba]]
Explanation: [a, b, c, b, a], [a, bcb, a] and [abcba] are the only partitions of "abcba" where each substring is a palindrome.
[Approach 1] Using Recursion and Backtracking
The main idea is to use backtracking to explore all combinations of substrings starting from each index, including a substring in the current partition only if it is a palindrome.
Step-By-Step Approach:
- Start at index 0 of the string.
- Generate all substrings starting from the current index.
- Check if the current substring is a palindrome.
- If it is, add it to the current partition path.
- Recursively continue from the next index.
- If the end of the string is reached, add the current path to the result.
- Backtrack by removing the last added substring and try the next possibility.
C++
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <numeric>
using namespace std;
// Check if the given string is a palindrome
bool isPalindrome(string& s) {
int i = 0, j = s.size() - 1;
while (i < j) {
if (s[i++] != s[j--])
return false;
}
return true;
}
// Recursive function to find all palindromic partitions
void backtrack(int idx, string& s, vector<string>& curr,
vector<vector<string>>& res) {
if (idx == s.size()) {
// Store valid partition
res.push_back(curr);
return;
}
string temp = "";
for (int i = idx; i < s.size(); ++i) {
temp += s[i];
if (isPalindrome(temp)) {
// Choose the substring
curr.push_back(temp);
// Explore further
backtrack(i + 1, s, curr, res);
// Backtrack
curr.pop_back();
}
}
}
// Return all palindromic partitions of string s
vector<vector<string>> palinParts(string& s) {
vector<vector<string>> res;
vector<string> curr;
backtrack(0, s, curr, res);
return res;
}
int main() {
string s = "geeks";
vector<vector<string>> res = palinParts(s);
// Print result: one partition per line
for (int i = 0; i < res.size(); ++i) {
for (int j = 0; j < res[i].size(); ++j) {
cout << res[i][j];
if (j != res[i].size() - 1) cout << " ";
}
cout << "\n";
}
return 0;
}
Java
import java.util.*;
class GfG {
// Check if a string is a palindrome
public boolean isPalindrome(String s) {
int i = 0, j = s.length() - 1;
while (i < j) {
if (s.charAt(i++) != s.charAt(j--)) return false;
}
return true;
}
// Recursive helper to find all palindromic partitions
public void backtrack(int idx, String s, List<String> curr,
List<ArrayList<String>> res) {
if (idx == s.length()) {
// Reached end, store current partition
res.add(new ArrayList<>(curr));
return;
}
StringBuilder temp = new StringBuilder();
for (int i = idx; i < s.length(); i++) {
temp.append(s.charAt(i));
String sub = temp.toString();
if (isPalindrome(sub)) {
// Choose the substring
curr.add(sub);
// Explore further
backtrack(i + 1, s, curr, res);
// Backtrack
curr.remove(curr.size() - 1);
}
}
}
// Returns all palindromic partitions
public ArrayList<ArrayList<String>> palinParts(String s) {
ArrayList<ArrayList<String>> res = new ArrayList<>();
backtrack(0, s, new ArrayList<>(), res);
return res;
}
public static void main(String[] args) {
GfG ob = new GfG();
String s = "geeks";
ArrayList<ArrayList<String>> res = ob.palinParts(s);
// Print each partition
for (ArrayList<String> part : res) {
System.out.println(String.join(" ", part));
}
}
}
Python
# Check if the string is a palindrome
def isPalindrome(s):
return s == s[::-1]
# Backtracking function to generate all palindromic partitions
def backtrack(idx, s, curr, res):
if idx == len(s):
# Save the current valid partition
res.append(curr[:])
return
temp = ""
for i in range(idx, len(s)):
temp += s[i]
if isPalindrome(temp):
# Choose substring
curr.append(temp)
# Explore further
backtrack(i + 1, s, curr, res)
# Backtrack
curr.pop()
# Generate all palindromic partitions and sort them
def palinParts(s):
res = []
backtrack(0, s, [], res)
return res
if __name__ == "__main__":
s = "geeks"
res = palinParts(s)
for part in res:
print(" ".join(part))
C#
using System;
using System.Collections.Generic;
using System.Linq;
class GfG {
// Check if a string is a palindrome
public bool isPalindrome(string s) {
int i = 0, j = s.Length - 1;
while (i < j) {
if (s[i++] != s[j--]) return false;
}
return true;
}
// Backtracking function to find all palindromic partitions
public void backtrack(int idx, string s, List<string> curr,
List<List<string>> res) {
if (idx == s.Length) {
// Valid partition found
res.Add(new List<string>(curr));
return;
}
string temp = "";
for (int i = idx; i < s.Length; i++) {
temp += s[i];
if (isPalindrome(temp)) {
// Choose the substring
curr.Add(temp);
// Explore further
backtrack(i + 1, s, curr, res);
// Backtrack
curr.RemoveAt(curr.Count - 1);
}
}
}
// Generate all palindromic partitions
public List<List<string>> palinParts(string s) {
List<List<string>> res = new List<List<string>>();
backtrack(0, s, new List<string>(), res);
return res;
}
public static void Main() {
GfG ob = new GfG();
string s = "geeks";
var res = ob.palinParts(s);
// Print each partition line by line
foreach (var part in res) {
Console.WriteLine(string.Join(" ", part));
}
}
}
JavaScript
// Check if a string is a palindrome
function isPalindrome(s) {
return s === s.split('').reverse().join('');
}
// Backtracking function to find all palindromic partitions
function backtrack(idx, s, curr, res) {
if (idx === s.length) {
// Valid partition found
res.push([...curr]);
return;
}
let temp = "";
for (let i = idx; i < s.length; i++) {
temp += s[i];
if (isPalindrome(temp)) {
// Choose the substring
curr.push(temp);
// Explore further
backtrack(i + 1, s, curr, res);
// Backtrack
curr.pop();
}
}
}
function palinParts(s) {
const res = [];
backtrack(0, s, [], res);
return res;
}
// Driver code
let s = "geeks";
let res = palinParts(s);
res.forEach(part => console.log(part.join(" ")));
Time Complexity: O(n² × 2n), for exploring all possible partitions (2n) and checking each substring for palindrome in O(n) time.
Auxiliary Space: O(n × 2n), for storing all palindromic partitions and using recursion stack up to depth n.
[Approach 2] Using Bit Manipulation
The main idea is systematically explores all ways to cut a string into parts and checks which ones consist only of palindromic substrings. It uses binary representation to model cut/no-cut choices between characters
- If there n characters in the string, then there are n-1 positions to put a space or say cut the string.
- Each of these positions can be given a binary number 1 (If a cut is made in this position) or 0 (If no cut is made in this position).
- This will give a total of 2n-1 partitions and for each partition check whether this partition is palindrome or not.
Illustration:
Input : geeks
0100
→ ["ge","eks"] (not valid)
1011
→ ["g","ee","k","s"] (valid)
1111
→ ["g","e","e","k","s"] (valid)
0000
→ ["geeks"] (not valid)
C++
#include <iostream>
#include <vector>
#include <string>
using namespace std;
vector<vector<string>> ans;
// Check if all substrings in the partition are palindromes
bool isAllPalindromes(vector<string> &partition) {
for (auto &str : partition) {
int i = 0, j = str.size() - 1;
while (i < j) {
if (str[i] != str[j])
return false;
i++;
j--;
}
}
return true;
}
// Generate partition of string based on the binary cut pattern
void createPartition(string &s, string &cutPattern) {
vector<string> currentPartition;
string subStr;
// Start the first substring with the first character
subStr.push_back(s[0]);
for (int i = 0; i < cutPattern.size(); i++) {
// If no cut, append next character to current substring
if (cutPattern[i] == '0') {
subStr.push_back(s[i + 1]);
}
// If cut, push current substring and start a new one
else {
currentPartition.push_back(subStr);
subStr.clear();
subStr.push_back(s[i + 1]);
}
}
// Push the last substring
currentPartition.push_back(subStr);
// Store partition if all substrings are palindromes
if (isAllPalindromes(currentPartition)) {
ans.push_back(currentPartition);
}
}
// Recursively generate all cut patterns (bit strings)
void generateCut(string &s, string &cutPattern) {
// When pattern is complete, create partition
if (cutPattern.size() == s.size() - 1) {
createPartition(s, cutPattern);
return;
}
// Try with a cut
cutPattern.push_back('1');
generateCut(s, cutPattern);
cutPattern.pop_back();
// Try without a cut
cutPattern.push_back('0');
generateCut(s, cutPattern);
cutPattern.pop_back();
}
// Generate all palindromic partitions of the string
vector<vector<string>> palinParts(string &s) {
string cutPattern;
generateCut(s, cutPattern);
return ans;
}
int main() {
string s = "geeks";
vector<vector<string>> result = palinParts(s);
for (auto &partition : result) {
for (auto &segment : partition) {
cout << segment << " ";
}
cout << "\n";
}
return 0;
}
Java
import java.util.ArrayList;
class GfG{
static ArrayList<ArrayList<String>> ans = new ArrayList<>();
// Check if all substrings in the partition are palindromes
static boolean isAllPalindromes(ArrayList<String> partition) {
for (String str : partition) {
int i = 0, j = str.length() - 1;
while (i < j) {
if (str.charAt(i) != str.charAt(j))
return false;
i++;
j--;
}
}
return true;
}
// Generate partition of string based on the binary cut pattern
static void createPartition(String s, String cutPattern) {
ArrayList<String> currentPartition = new ArrayList<>();
StringBuilder subStr = new StringBuilder();
// Start the first substring with the first character
subStr.append(s.charAt(0));
for (int i = 0; i < cutPattern.length(); i++) {
// If no cut, append next character to current substring
if (cutPattern.charAt(i) == '0') {
subStr.append(s.charAt(i + 1));
}
// If cut, push current substring and start a new one
else {
currentPartition.add(subStr.toString());
subStr = new StringBuilder();
subStr.append(s.charAt(i + 1));
}
}
// Push the last substring
currentPartition.add(subStr.toString());
// Store partition if all substrings are palindromes
if (isAllPalindromes(currentPartition)) {
ans.add(currentPartition);
}
}
// Recursively generate all cut patterns (bit strings)
static void generateCut(String s, String cutPattern) {
// When pattern is complete, create partition
if (cutPattern.length() == s.length() - 1) {
createPartition(s, cutPattern);
return;
}
// Try with a cut
generateCut(s, cutPattern + '1');
// Try without a cut
generateCut(s, cutPattern + '0');
}
// Generate all palindromic partitions of the string
static ArrayList<ArrayList<String>> palinParts(String s) {
generateCut(s, "");
return ans;
}
public static void main(String[] args) {
String s = "geeks";
ArrayList<ArrayList<String>> result = palinParts(s);
for (ArrayList<String> partition : result) {
for (String segment : partition) {
System.out.print(segment + " ");
}
System.out.println();
}
}
}
Python
# Stores all valid palindromic partitions
ans = []
# Check if all substrings in the partition are palindromes
def isAllPalindromes(partition):
for s in partition:
i, j = 0, len(s) - 1
while i < j:
if s[i] != s[j]:
return False
i += 1
j -= 1
return True
# Generate partition of string based on the binary cut pattern
def createPartition(s, cutPattern):
currentPartition = []
subStr = s[0]
for i in range(len(cutPattern)):
# If no cut, append next character to current substring
if cutPattern[i] == '0':
subStr += s[i + 1]
# If cut, push current substring and start a new one
else:
currentPartition.append(subStr)
subStr = s[i + 1]
# Push the last substring
currentPartition.append(subStr)
# Store partition if all substrings are palindromes
if isAllPalindromes(currentPartition):
ans.append(currentPartition)
# Recursively generate all cut patterns (bit strings)
def generateCut(s, cutPattern):
# When pattern is complete, create partition
if len(cutPattern) == len(s) - 1:
createPartition(s, cutPattern)
return
# Try with a cut
generateCut(s, cutPattern + '1')
# Try without a cut
generateCut(s, cutPattern + '0')
# Generate all palindromic partitions of the string
def palinParts(s):
generateCut(s, "")
return ans
if __name__ == "__main__":
s = "geeks"
result = palinParts(s)
for partition in result:
print(" ".join(partition))
C#
using System;
using System.Collections.Generic;
using System.Text;
class GfG{
static List<List<string>> ans = new List<List<string>>();
// Check if all substrings in the partition are palindromes
static bool isAllPalindromes(List<string> partition){
foreach (string str in partition){
int i = 0, j = str.Length - 1;
while (i < j){
if (str[i] != str[j])
return false;
i++;
j--;
}
}
return true;
}
// Generate partition of string based on the binary cut pattern
static void createPartition(string s, string cutPattern){
List<string> currentPartition = new List<string>();
StringBuilder subStr = new StringBuilder();
// Start the first substring with the first character
subStr.Append(s[0]);
for (int i = 0; i < cutPattern.Length; i++){
// If no cut, append next character to current substring
if (cutPattern[i] == '0'){
subStr.Append(s[i + 1]);
}
// If cut, push current substring and start a new one
else{
currentPartition.Add(subStr.ToString());
subStr.Clear();
subStr.Append(s[i + 1]);
}
}
// Push the last substring
currentPartition.Add(subStr.ToString());
// Store partition if all substrings are palindromes
if (isAllPalindromes(currentPartition))
{
ans.Add(currentPartition);
}
}
// Recursively generate all cut patterns (bit strings)
static void generateCut(string s, string cutPattern)
{
// When pattern is complete, create partition
if (cutPattern.Length == s.Length - 1)
{
createPartition(s, cutPattern);
return;
}
// Try with a cut
generateCut(s, cutPattern + '1');
// Try without a cut
generateCut(s, cutPattern + '0');
}
// Generate all palindromic partitions of the string
static List<List<string>> palinParts(string s){
generateCut(s, "");
return ans;
}
static void Main()
{
string s = "geeks";
List<List<string>> result = palinParts(s);
foreach (var partition in result)
{
foreach (var segment in partition)
{
Console.Write(segment + " ");
}
Console.WriteLine();
}
}
}
JavaScript
// Stores all valid palindromic partitions
let ans = [];
// Check if all substrings in the partition are palindromes
function isAllPalindromes(partition) {
for (let str of partition) {
let i = 0, j = str.length - 1;
while (i < j) {
if (str[i] !== str[j]) {
return false;
}
i++;
j--;
}
}
return true;
}
// Generate partition of string based on the binary cut pattern
function createPartition(s, cutPattern) {
let currentPartition = [];
let subStr = s[0];
for (let i = 0; i < cutPattern.length; i++) {
// If no cut, append next character to current substring
if (cutPattern[i] === '0') {
subStr += s[i + 1];
}
// If cut, push current substring and start a new one
else {
currentPartition.push(subStr);
subStr = s[i + 1];
}
}
// Push the last substring
currentPartition.push(subStr);
// Store partition if all substrings are palindromes
if (isAllPalindromes(currentPartition)) {
ans.push(currentPartition);
}
}
// Recursively generate all cut patterns (bit strings)
function generateCut(s, cutPattern) {
// When pattern is complete, create partition
if (cutPattern.length === s.length - 1) {
createPartition(s, cutPattern);
return;
}
// Try with a cut
generateCut(s, cutPattern + '1');
// Try without a cut
generateCut(s, cutPattern + '0');
}
// Generate all palindromic partitions of the string
function palinParts(s) {
generateCut(s, "");
return ans;
}
// Driver Code
const s = "geeks";
const result = palinParts(s);
for (const partition of result) {
console.log(partition.join(" "));
}
Time Complexity: O(n² × 2n) for generating all possible partitions (2n) and checking each partition for palindromes (up to O(n2) per partition).
Auxiliary Space: O(n × 2n), to store all palindromic partitions, each potentially having up to n
substrings.
[Expected Approach] Backtracking with Memoization
The Idea is uses dynamic programming to precompute all substrings of the input string that are palindromes in O(n²) time. This precomputation helps in quickly checking whether a substring is a palindrome during the recursive backtracking phase. Then, it uses backtracking to explore all possible partitions of the string and collects only those partitions where every substring is a palindrome.
C++
#include <iostream>
#include <vector>
#include <string>
using namespace std;
// Precompute all palindromic substrings in s
void palindromes(const string& s, vector<vector<bool>> &dp) {
int n = s.size();
// All single characters are palindromes
for (int i = 0; i < n; ++i)
dp[i][i] = true;
// Check two-character substrings
for (int i = 0; i < n - 1; ++i)
dp[i][i + 1] = (s[i] == s[i + 1]);
// Check substrings of length 3 or more using bottom-up DP
for (int len = 3; len <= n; ++len) {
for (int i = 0; i <= n - len; ++i) {
int j = i + len - 1;
dp[i][j] = (s[i] == s[j]) && dp[i + 1][j - 1];
}
}
}
// Recursive function to find all palindromic partitions
void backtrack(int idx, const string& s, vector<string>& curr,
vector<vector<string>>& res, vector<vector<bool>> &dp) {
// If we have reached the end of the string, store current partition
if (idx == s.size()) {
res.push_back(curr);
return;
}
// Try all substrings starting from index idx
for (int i = idx; i < s.size(); ++i) {
// If s[idx..i] is a palindrome, we can include it
if (dp[idx][i]) {
// Choose the substring
curr.push_back(s.substr(idx, i - idx + 1));
// Explore further from next index
backtrack(i + 1, s, curr, res, dp);
// Undo the choice (backtrack)
curr.pop_back();
}
}
}
// Return all palindromic partitions of string s
vector<vector<string>> palinParts(string& s) {
// DP table to store if substring s[i..j] is a palindrome
vector<vector<bool>> dp(s.size()+1, vector<bool> (s.size()+1, false));
// Precompute all palindromic substrings using DP
palindromes(s, dp);
// Final result
vector<vector<string>> res;
// Current partition
vector<string> curr;
// Begin backtracking from index 0
backtrack(0, s, curr, res, dp);
return res;
}
int main() {
string s = "geeks";
// Get all palindromic partitions
vector<vector<string>> res = palinParts(s);
// Print each valid partition
for (auto& partition : res) {
for (auto& part : partition) {
cout << part << " ";
}
cout << "\n";
}
return 0;
}
Java
import java.util.ArrayList;
class GfG {
// Precompute all palindromic substrings in s
public static void palindromes(String s, boolean[][] dp) {
int n = s.length();
// All single characters are palindromes
for (int i = 0; i < n; ++i)
dp[i][i] = true;
// Check two-character substrings
for (int i = 0; i < n - 1; ++i)
dp[i][i + 1] = (s.charAt(i) == s.charAt(i + 1));
// Check substrings of length 3 or more using bottom-up DP
for (int len = 3; len <= n; ++len) {
for (int i = 0; i <= n - len; ++i) {
int j = i + len - 1;
dp[i][j] = (s.charAt(i) == s.charAt(j)) && dp[i + 1][j - 1];
}
}
}
// Recursive function to find all palindromic partitions
public static void backtrack(int idx, String s, ArrayList<String> curr,
ArrayList<ArrayList<String>> res, boolean[][] dp) {
// If we have reached the end of the string, store current partition
if (idx == s.length()) {
res.add(new ArrayList<>(curr));
return;
}
// Try all substrings starting from index idx
for (int i = idx; i < s.length(); ++i) {
// If s[idx..i] is a palindrome, we can include it
if (dp[idx][i]) {
// Choose the substring
curr.add(s.substring(idx, i + 1));
// Explore further from next index
backtrack(i + 1, s, curr, res, dp);
// Undo the choice (backtrack)
curr.remove(curr.size() - 1);
}
}
}
// Return all palindromic partitions of string s
public static ArrayList<ArrayList<String>> palinParts(String s) {
// DP table to store if substring s[i..j] is a palindrome
boolean[][] dp = new boolean[s.length()][s.length()];
// Precompute all palindromic substrings using DP
palindromes(s, dp);
// Final result
ArrayList<ArrayList<String>> res = new ArrayList<>();
// Current partition
ArrayList<String> curr = new ArrayList<>();
// Begin backtracking from index 0
backtrack(0, s, curr, res, dp);
return res;
}
public static void main(String[] args) {
String s = "geeks";
// Get all palindromic partitions
ArrayList<ArrayList<String>> res = palinParts(s);
// Print each valid partition
for (ArrayList<String> partition : res) {
for (String part : partition) {
System.out.print(part + " ");
}
System.out.println();
}
}
}
Python
# Precompute all palindromic substrings in s
def palindromes(s, dp):
n = len(s)
# All single characters are palindromes
for i in range(n):
dp[i][i] = True
# Check two-character substrings
for i in range(n - 1):
dp[i][i + 1] = (s[i] == s[i + 1])
# Check substrings of length 3 or more using bottom-up DP
for length in range(3, n + 1):
for i in range(n - length + 1):
j = i + length - 1
dp[i][j] = (s[i] == s[j]) and dp[i + 1][j - 1]
# Recursive function to find all palindromic partitions
def backtrack(idx, s, curr, res, dp):
# If we have reached the end of the string, store current partition
if idx == len(s):
res.append(list(curr))
return
# Try all substrings starting from index idx
for i in range(idx, len(s)):
# If s[idx..i] is a palindrome, we can include it
if dp[idx][i]:
# Choose the substring
curr.append(s[idx:i + 1])
# Explore further from next index
backtrack(i + 1, s, curr, res, dp)
# Undo the choice (backtrack)
curr.pop()
# Return all palindromic partitions of string s
def palinParts(s):
n = len(s)
# DP table to store if substring s[i..j] is a palindrome
dp = [[False] * n for _ in range(n)]
# Precompute all palindromic substrings using DP
palindromes(s, dp)
# Final result
res = []
# Current partition
curr = []
# Begin backtracking from index 0
backtrack(0, s, curr, res, dp)
return res
if __name__ == "__main__":
s = "geeks"
# Get all palindromic partitions
result = palinParts(s)
# Print each valid partition
for partition in result:
print(" ".join(partition))
C#
using System;
using System.Collections.Generic;
class GfG{
// Precompute all palindromic substrings in s
static void palindromes(string s, bool[,] dp){
int n = s.Length;
// All single characters are palindromes
for (int i = 0; i < n; ++i)
dp[i, i] = true;
// Check two-character substrings
for (int i = 0; i < n - 1; ++i)
dp[i, i + 1] = (s[i] == s[i + 1]);
// Check substrings of length 3 or more using bottom-up DP
for (int len = 3; len <= n; ++len){
for (int i = 0; i <= n - len; ++i){
int j = i + len - 1;
dp[i, j] = (s[i] == s[j]) && dp[i + 1, j - 1];
}
}
}
// Recursive function to find all palindromic partitions
static void backtrack(int idx, string s, List<string> curr,
List<List<string>> res, bool[,] dp){
// If we have reached the end of the string, store current partition
if (idx == s.Length){
res.Add(new List<string>(curr));
return;
}
// Try all substrings starting from index idx
for (int i = idx; i < s.Length; ++i){
// I s[idx..i] is a palindrome, we can include it
if (dp[idx, i]){
// Choose the substring
curr.Add(s.Substring(idx, i - idx + 1));
// Explore further from next index
backtrack(i + 1, s, curr, res, dp);
// Undo the choice (backtrack)
curr.RemoveAt(curr.Count - 1);
}
}
}
// Return all palindromic partitions of string s
static List<List<string>> palinParts(string s){
// DP table to store if substring s[i..j] is a palindrome
bool[,] dp = new bool[s.Length, s.Length];
// Precompute all palindromic substrings using DP
palindromes(s, dp);
// Final result
List<List<string>> res = new List<List<string>>();
// Current partition
List<string> curr = new List<string>();
// Begin backtracking from index 0
backtrack(0, s, curr, res, dp);
return res;
}
static void Main(){
string s = "geeks";
// Get all palindromic partitions
var res = palinParts(s);
// Print each valid partition
foreach (var partition in res){
foreach (var part in partition){
Console.Write(part + " ");
}
Console.WriteLine();
}
}
}
JavaScript
// Precompute all palindromic substrings in s
function palindromes(s, dp) {
const n = s.length;
// All single characters are palindromes
for (let i = 0; i < n; i++)
dp[i][i] = true;
// Check two-character substrings
for (let i = 0; i < n - 1; i++)
dp[i][i + 1] = (s[i] === s[i + 1]);
// Check substrings of length 3 or more using bottom-up DP
for (let len = 3; len <= n; len++) {
for (let i = 0; i <= n - len; i++) {
const j = i + len - 1;
dp[i][j] = (s[i] === s[j]) && dp[i + 1][j - 1];
}
}
}
// Recursive function to find all palindromic partitions
function backtrack(idx, s, curr, res, dp) {
// If we have reached the end of the string, store current partition
if (idx === s.length) {
res.push([...curr]);
return;
}
// Try all substrings starting from index idx
for (let i = idx; i < s.length; i++) {
// If s[idx..i] is a palindrome, we can include it
if (dp[idx][i]) {
// Choose the substring
curr.push(s.substring(idx, i + 1));
// Explore further from next index
backtrack(i + 1, s, curr, res, dp);
// Undo the choice (backtrack)
curr.pop();
}
}
}
// Return all palindromic partitions of string s
function palinParts(s) {
const n = s.length;
const dp = Array.from({ length: n }, () => Array(n).fill(false));
// Precompute all palindromic substrings using DP
palindromes(s, dp);
// Final result
const res = [];
// Current partition
const curr = [];
// Begin backtracking from index 0
backtrack(0, s, curr, res, dp);
return res;
}
// Example usage
const s = "geeks";
// Get all palindromic partitions
const result = palinParts(s);
// Print each valid partition
for (const partition of result) {
console.log(partition.join(" "));
}
Time Complexity: O(n² + 2n×n), (n2) time for precomputing palindromic substrings and O(2n × n) for backtracking through all partitions.
Auxiliary Space: O(n2), for the DP table and O(n) for the recursion stack and temporary storage during backtracking.
A similar optimization can be applied to the bitmask-based approach by precomputing all palindromic substrings in O(n²) using dynamic programming. This reduces the palindrome-checking time per partition from O(n) to O(1), thereby improving the overall time complexity from O(n2 × 2n) to O(n × 2n).
Similar Reads
Print all Palindromic Partitions of a String using Backtracking Given a string s, find all possible ways to partition it such that every substring in the partition is a palindrome.Examples: Input: s = "geeks"Output: [[g, e, e, k, s], [g, ee, k, s]]Explanation: [g, e, e, k, s] and [g, ee, k, s] are the only partitions of "geeks" where each substring is a palindro
15+ min read
Print all palindrome permutations of a string Given a string s, consisting of lowercase Latin characters [a-z]. Find out all the possible palindromes that can be generated using the letters of the string and print them in lexicographical order.Note: Return an empty array if no possible palindromic string can be formed.Examples:Input: s = aabcbO
10 min read
Print all Palindromic Partitions of a String using Bit Manipulation Given a string, find all possible palindromic partitions of a given string. Note that this problem is different from Palindrome Partitioning Problem, there the task was to find the partitioning with minimum cuts in input string. Here we need to print all possible partitions. Example: Input: nitinOut
10 min read
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
Find all Palindrome Strings in given Array of strings Given an array of strings arr[] of size N where each string consists only of lowercase English letter. The task is to find all palindromic string in the array. Print -1 if no palindrome is present in the given array. Examples: Input: arr[] = {"abc", "car", "ada", "racecar", "cool"}Output: "ada", "ra
6 min read
Count of K-size substrings having palindromic permutations Given string str consists of only lowercase alphabets and an integer K, the task is to count the number of substrings of size K such that any permutation of the substring is a palindrome. Examples: Input: str = "abbaca", K = 3 Output: 3 Explanation: The substrings of size 3 whose permutation is pali
9 min read