Open In App

Print all Palindromic Partitions of a String using Backtracking

Given a string, find all possible palindromic partitions of 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: nitin
Output: n i t i n
n iti n
nitin



Input: geeks
Output: g e e k s
g ee k s

Brute Force Approach:

The idea is to use recursion and backtracking.

Below is the implementation of above approach.




#include <bits/stdc++.h>
using namespace std;
 
class GFG {
 
public:
    // Check whether the string is palindrom or not.
    bool checkPalindrome(string& s)
    {
        int n = s.size();
        int i = 0, j = n - 1;
        while (i < j) {
            if (s[i] != s[j])
                return false;
            i++;
            j--;
        }
        return true;
    }
    // Recursive function which takes starting index idx
    // and generates all substrings starting at idx.
    // If substring generated is palindrome it adds to
    // current list and makes a recursive call for
    // remaining  string.
    void Partition(vector<vector<string> >& res, string& s,
                   int idx, vector<string>& curr)
    {
        // If we reach the end of string at the current list
        // to the result.
        if (idx == s.size()) {
            res.push_back(curr);
            return;
        }
        // Stores the current substring.
        string t;
        for (int i = idx; i < s.size(); i++) {
            t.push_back(s[i]);
 
            // Check whether the string is palindrome is
            // not.
            if (checkPalindrome(t)) {
 
                // Adds the string to current list
                curr.push_back(t);
 
                // Recursive call for the remaining string
                Partition(res, s, i + 1, curr);
 
                // Remove the string from the current
                // string.
                curr.pop_back();
            }
        }
    }
};
// Driver code
int main()
{
    GFG ob;
    // Stores all the partition
    vector<vector<string> > res;
    string s = "geeks";
 
    // Starting index of string
    int idx = 0;
 
    // Current list
    vector<string> curr;
    ob.Partition(res, s, idx, curr);
    for (auto& v : res) {
        for (auto& it : v) {
            cout << it << " ";
        }
        cout << "\n";
    }
    return 0;
}




/*package whatever //do not write package name here */
 
import java.io.*;
import java.util.ArrayList;
 
class GFG {
 
    //funtion to check whether partitioned string is palindrome or not
    public boolean checkPalindrome(String s) {
        int n = s.length();
        int i = 0;
        int j = n-1;
        while(i < j) {
            if(s.charAt(i) != s.charAt(j))
                return false;
 
            i++;
            j--;
        }
        return true;
    }
 
    // Recursive funtion which takes index ind and generates all substrings starting at ind.
    // if substring generated is palindrome it adds to current list and makes a recursive call for remaining string
 
    public void partition(ArrayList<ArrayList<String>> res, String s, int ind, ArrayList<String> curr) {
        // if we reach the end of string
        // add the current list to the result
 
        if(ind == s.length()) {
            res.add(new ArrayList<String>(curr));
            return;
        }
 
        // Store the current substring
        String temp = "";
 
        for(int i = ind; i < s.length(); i++) {
            temp += s.charAt(i);
 
            // check if string temp is palindrome or not
            if(checkPalindrome(temp)){
 
                // adds the string to current list
                curr.add(temp);
 
                // Recursive call for the remaining string
                partition(res, s, i+1, curr);
 
                // Remove the string from the current list - (backtracking)
                curr.remove(curr.size()-1);
            }
        }
         
    }
    public static void main(String[] args) {
 
        // creating obj of GFG class
        GFG obj = new GFG();
 
        // Stores all partitions generated at the end
        ArrayList<ArrayList<String>> res = new ArrayList<>();
         
        String s = "geeks";
 
        int ind = 0;
 
        // Store the partition at current iteration
        ArrayList<String> curr = new ArrayList<>();
 
        // calling funtion to get partition
        obj.partition(res, s, ind, curr);
 
        for(ArrayList<String> iter : res) {
            System.out.println(iter);
        }
    }
}




# Python implementation
class GFG:
 
    def checkPalindrome(self, s):
        n = len(s)
        i, j = 0, n - 1
        while i < j:
            if s[i] != s[j]:
                return False
            i += 1
            j -= 1
        return True
 
    def partition(self, res, s, ind, curr):
        if ind == len(s):
            res.append(list(curr))
            return
 
        temp = ""
        for i in range(ind, len(s)):
            temp += s[i]
            if self.checkPalindrome(temp):
                curr.append(temp)
                self.partition(res, s, i + 1, curr)
                curr.pop()
 
    def main(self):
        obj = GFG()
        res = []
        s = "geeks"
        ind = 0
        curr = []
        obj.partition(res, s, ind, curr)
 
        for iter in res:
            print(iter)
 
# Creating an instance of GFG class
gfg_obj = GFG()
gfg_obj.main()




using System;
using System.Collections.Generic;
 
class GFG {
    public bool CheckPalindrome(string s)
    {
        int n = s.Length;
        int i = 0, j = n - 1;
 
        // Check whether the string is a palindrome
        while (i < j) {
            if (s[i] != s[j])
                return false;
            i++;
            j--;
        }
        return true;
    }
 
    public void Partition(List<List<string> > res, string s,
                          int idx, List<string> curr)
    {
        // If we reach the end of the string, add the
        // current list to the result.
        if (idx == s.Length) {
            res.Add(new List<string>(curr));
            return;
        }
 
        // Stores the current substring.
        string t = "";
        for (int i = idx; i < s.Length; i++) {
            t += s[i];
 
            // Check whether the string is a palindrome.
            if (CheckPalindrome(t)) {
                // Add the string to the current list.
                curr.Add(t);
 
                // Recursive call for the remaining string.
                Partition(res, s, i + 1, curr);
 
                // Remove the string from the current list.
                curr.RemoveAt(curr.Count - 1);
            }
        }
    }
 
    public static void Main(string[] args)
    {
        GFG ob = new GFG();
 
        // Stores all the partitions
        List<List<string> > res = new List<List<string> >();
        string s = "geeks";
 
        // Starting index of the string
        int idx = 0;
 
        // Current list
        List<string> curr = new List<string>();
 
        ob.Partition(res, s, idx, curr);
 
        foreach(var v in res)
        {
            foreach(var it in v)
            {
                Console.Write(it + " ");
            }
            Console.WriteLine();
        }
    }
}




class GFG {
    // Check whether the string is a palindrome or not.
    checkPalindrome(s) {
        let n = s.length;
        let i = 0, j = n - 1;
        while (i < j) {
            if (s[i] !== s[j]) {
                return false;
            }
            i++;
            j--;
        }
        return true;
    }
 
    // Recursive function which takes starting index idx
    // and generates all substrings starting at idx.
    // If the substring generated is a palindrome, it adds it
    // to the current list and makes a recursive call for the
    // remaining string.
    partition(res, s, idx, curr) {
        // If we reach the end of the string, add the current list to the result.
        if (idx === s.length) {
            res.push([...curr]);
            return;
        }
        // Stores the current substring.
        let t = '';
        for (let i = idx; i < s.length; i++) {
            t += s[i];
 
            // Check whether the string is a palindrome or not.
            if (this.checkPalindrome(t)) {
                // Add the string to the current list.
                curr.push(t);
 
                // Recursive call for the remaining string.
                this.partition(res, s, i + 1, curr);
 
                // Remove the string from the current list.
                curr.pop();
            }
        }
    }
}
 
// Driver code
function main() {
    const ob = new GFG();
    // Stores all the partitions.
    const res = [];
    const s = "geeks";
 
    // Starting index of the string.
    let idx = 0;
 
    // Current list.
    const curr = [];
    ob.partition(res, s, idx, curr);
 
    // Print the result.
    for (let v of res) {
        console.log(v.join(' '));
    }
}
 
main();

Output
g e e k s 
g ee k s 





Time complexity: O(n*2n), where n is the size of the string. There are 2n possibilities of partitioning the string of length n, and for each possibility, we are checking if the string is a palindrome that costs O(n) time. Hence the overall time complexity is O(n*2n).
Auxiliary Space: O(2n), to store all possible partition of string.

Also read about the Bit Manipulation approach or this problem.


Article Tags :