Skip to content
Related Articles
Get the best out of our app
GFG App
Open App
geeksforgeeks
Browser
Continue

Related Articles

Given a string, print all possible palindromic partitions

Improve Article
Save Article
Like Article
Improve Article
Save Article
Like Article

Given a string, find all possible palindromic partitions of given string.
Example: 
 

AllPalindromPArtition

 

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.
The idea is to go through every substring starting from first character, check if it is palindrome. If yes, then add the substring to solution and recur for remaining part. Below is complete algorithm.
Below is the implementation of above idea.
 

Output

n i t i n 
n iti n 
nitin 

Time complexity: O(n*2n)

Auxiliary Space: O(n2)

Approach 2: Expand around every palindrome

The idea is to split the string into all palindromes of length 1 that is convert the string to a list of its characters (but as string data type) and then expand the smaller palindromes to bigger palindromes by checking if its left and right (reversed) are equal or not if they are equal then merge them and solve for new list recursively. Also if two adjacent strings of this list are equal (when one of them is reversed), merging them would also give a palindrome so merge them and solve recursively.

C++




#include <bits/stdc++.h>
using namespace std;
 
class GFG {
public:
    void solve(vector<string> arr) {
        res.insert(arr); // add current partitioning to result
        if (arr.size() <= 1) {  // Base case when there is nothing to merge
            return;
        }
        for (int i = 1; i < arr.size(); i++) {
            if (arr[i-1] == string(arr[i].rbegin(), arr[i].rend())) { // When two adjacent such that one is reverse of another
                vector<string> brr(arr.begin(), arr.begin()+i-1);
                brr.push_back(arr[i-1]+arr[i]);
                brr.insert(brr.end(), arr.begin()+i+1, arr.end());
                solve(brr);
            }
            if (i+1 < arr.size() && arr[i-1] == string(arr[i+1].rbegin(), arr[i+1].rend())) {  // All are individually palindrome,
              // when one left and one right of i are reverse of each other then we can merge
              // the three of them to form a new partitioning way
                vector<string> brr(arr.begin(), arr.begin()+i-1);
                brr.push_back(arr[i-1]+arr[i]+arr[i+1]);
                brr.insert(brr.end(), arr.begin()+i+2, arr.end());
                solve(brr);
            }
        }
    }
 
    vector<vector<string>> getGray(string S) {
        res.clear(); // result is a set of tuples to avoid same partition multiple times
        vector<string> s;
        for (char c : S) {
            s.emplace_back(1, c);
        }
        solve(s); // Call recursive function to solve for S
        vector<vector<string>> res_v(res.begin(), res.end());
        sort(res_v.begin(), res_v.end());
        return res_v;
    }
 
private:
    set<vector<string>> res; // set of partition vectors to avoid duplicates
};
 
int main() {
    GFG ob;
    vector<vector<string>> allPart = ob.getGray("geeks");
    for (auto& v : allPart) {
        for (auto& s : v) {
            cout << s << " ";
        }
        cout << "\n";
    }
    return 0;
}


Java




// Java equivalent of the Python code above
 
import java.util.*;
 
class GFG {
    // Method to solve the problem recursively
    public void solve(ArrayList<String> arr,
                      HashSet<ArrayList<String> > res)
    {
 
        // Add current partitioning to the result set
        res.add(new ArrayList<String>(arr));
 
        // Base case when there is nothing to merge
        if (arr.size() <= 1) {
            return;
        }
 
        // Check for all possible merges
        for (int i = 1; i < arr.size(); i++) {
 
            // When two adjacent strings are such that one
            // is reverse of another
            if (arr.get(i - 1).equals(
                    new StringBuilder(arr.get(i))
                        .reverse()
                        .toString())) {
                ArrayList<String> brr
                    = new ArrayList<String>();
                brr.addAll(arr.subList(0, i - 1));
                brr.add(arr.get(i - 1) + arr.get(i));
                brr.addAll(arr.subList(i + 1, arr.size()));
                solve(brr, res);
            }
 
            // When one string left and one right of i are
            // reverse of each other then we can merge the
            // three of them to form a new partitioning way
            if (i + 1 < arr.size()
                && arr.get(i - 1).equals(
                    new StringBuilder(arr.get(i + 1))
                        .reverse()
                        .toString())) {
                ArrayList<String> brr
                    = new ArrayList<String>();
                brr.addAll(arr.subList(0, i - 1));
                brr.add(arr.get(i - 1) + arr.get(i)
                        + arr.get(i + 1));
                brr.addAll(arr.subList(i + 2, arr.size()));
                solve(brr, res);
            }
        }
    }
 
    // Method to get all valid partitionings of a given
    // string
    public ArrayList<ArrayList<String> > getGray(String S)
    {
        HashSet<ArrayList<String> > res
            = new HashSet<ArrayList<String> >();
        ArrayList<String> arr = new ArrayList<String>(
            Arrays.asList(S.split("")));
        solve(arr, res);
        ArrayList<ArrayList<String> > sortedRes
            = new ArrayList<ArrayList<String> >(res);
        Collections.sort(
            sortedRes,
            new Comparator<ArrayList<String> >() {
                @Override
                public int compare(ArrayList<String> a,
                                   ArrayList<String> b)
                {
                    for (int i = 0;
                         i < Math.min(a.size(), b.size());
                         i++) {
                        int cmp
                            = a.get(i).compareTo(b.get(i));
                        if (cmp != 0) {
                            return cmp;
                        }
                    }
                    return Integer.compare(a.size(),
                                           b.size());
                }
            });
        return sortedRes;
    }
 
    // Driver code
    public static void main(String[] args)
    {
 
        // Create object of GFG class
        GFG ob = new GFG();
 
        // Get all valid partitionings of the string "geeks"
        ArrayList<ArrayList<String> > allPart
            = ob.getGray("geeks");
 
        // Print all partitionings
        for (ArrayList<String> partition : allPart) {
            for (String str : partition) {
                System.out.print(str + " ");
            }
            System.out.println();
        }
    }
}


Python3




class GFG:
    def solve(self, arr):
        self.res.add(tuple(arr)) # add current partitioning to result
        if len(arr)<=1# Base case when there is nothing to merge
            return
        for i in range(1,len(arr)):
            if arr[i-1]==arr[i][::-1]: # When two adjacent such that one is reverse of another
                brr = arr[:i-1] + [arr[i-1]+arr[i]] + arr[i+1:]
                self.solve(brr)
            if i+1<len(arr) and arr[i-1]==arr[i+1][::-1]:  # All are individually palindrome,
              # when one left and one right of i are reverse of each other then we can merge
              # the three of them to form a new partitioning way
                brr = arr[:i-1] + [arr[i-1]+arr[i]+arr[i+1]] + arr[i+2:]
                self.solve(brr)
    def getGray(self, S):
        self.res = set()  # result is a set of tuples to avoid same partition multiple times
        self.solve(list(S)) # Call recursive function to solve for S
        return sorted(list(self.res))
# Driver Code
if __name__ == '__main__':
    ob = GFG()
    allPart = ob.getGray("geeks")
    for i in range(len(allPart)):
        for j in range(len(allPart[i])):
            print(allPart[i][j], end = " ")
        print()
# This code is contributed by Gautam Wadhwani


C#




// C# Program for the above approach
 
using System;
using System.Collections.Generic;
using System.Linq;
 
class GFG {
  // Method to solve the problem recursively
  public void Solve(List<string> arr, HashSet<List<string>> res) {
 
    // Add current partitioning to the result set
    res.Add(new List<string>(arr));
 
    // Base case when there is nothing to merge
    if (arr.Count <= 1) {
      return;
    }
 
    // Check for all possible merges
    for (int i = 1; i < arr.Count; i++) {
 
      // When two adjacent strings are such that one
      // is reverse of another
      if (arr[i - 1] == new string(arr[i].Reverse().ToArray())) {
        List<string> brr = new List<string>();
        brr.AddRange(arr.GetRange(0, i - 1));
        brr.Add(arr[i - 1] + arr[i]);
        brr.AddRange(arr.GetRange(i + 1, arr.Count - i - 1));
        Solve(brr, res);
      }
 
      // When one string left and one right of i are
      // reverse of each other then we can merge the
      // three of them to form a new partitioning way
      if (i + 1 < arr.Count && arr[i - 1] == new string(arr[i + 1].Reverse().ToArray())) {
        List<string> brr = new List<string>();
        brr.AddRange(arr.GetRange(0, i - 1));
        brr.Add(arr[i - 1] + arr[i] + arr[i + 1]);
        brr.AddRange(arr.GetRange(i + 2, arr.Count - i - 2));
        Solve(brr, res);
      }
    }
  }
 
  // Method to get all valid partitionings of a given
  // string
  public List<List<string>> GetGray(string S) {
    HashSet<List<string>> res = new HashSet<List<string>>();
    List<string> arr = S.Select(c => c.ToString()).ToList();
    Solve(arr, res);
    List<List<string>> sortedRes = new List<List<string>>(res);
    sortedRes.Sort((a, b) => {
      for (int i = 0; i < Math.Min(a.Count, b.Count); i++) {
        int cmp = a[i].CompareTo(b[i]);
        if (cmp != 0) {
          return cmp;
        }
      }
      return a.Count.CompareTo(b.Count);
    });
    return sortedRes;
  }
 
  // Driver code
  public static void Main(string[] args) {
 
    // Create object of GFG class
    GFG ob = new GFG();
 
    // Get all valid partitionings of the string "geeks"
    List<List<string>> allPart = ob.GetGray("geeks");
 
    // Print all partitionings
    foreach (List<string> partition in allPart) {
      foreach (string str in partition) {
        Console.Write(str + " ");
      }
      Console.WriteLine();
    }
  }
}
 
// This code is contributed by codebraxnzt


Javascript




// Javascript equivalent
class GFG {
    solve(arr) {
        this.res.add(Array.from(arr))  // add current partitioning to result
        if (arr.length <= 1) { // Base case when there is nothing to merge
            return;
        }
        for (let i = 1; i < arr.length; i++) {
            if (arr[i - 1] == arr[i].split("").reverse().join("")) { // When two adjacent such that one is reverse of another
                let brr = arr.slice(0, i-1).concat([arr[i-1]+arr[i]]).concat(arr.slice(i+1));
                this.solve(brr);
            }
            if (i+1<arr.length && arr[i-1] == arr[i+1].split("").reverse().join(""))
            {
             
            // All are individually palindrome,
              // when one left and one right of i are reverse of each other then we can merge
              // the three of them to form a new partitioning way
                let brr = arr.slice(0, i-1).concat([arr[i-1]+arr[i]+arr[i+1]]).concat(arr.slice(i+2));
                this.solve(brr);
            }
        }
    }
    getGray(S) {
        this.res = new Set();  // result is a set of tuples to avoid same partition multiple times
        this.solve(S.split("")); // Call recursive function to solve for S
        let result = Array.from(this.res);
        return result.sort();
    }
}
// Driver Code
 
    let ob = new GFG();
    let allPart = ob.getGray("geeks");
    for (let i=0;i<allPart.length;i++) { temp= "";
        for (let j=0;j<allPart[i].length;j++) {
            temp = temp + allPart[i][j] + " ";
        }
        console.log(temp);
    }


Output

g e e k s 
g ee k s 

Time complexity: O(n*2n)

Auxiliary Space: O(n2)

This article is contributed by Ekta Goel. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.

 


My Personal Notes arrow_drop_up
Last Updated : 28 Mar, 2023
Like Article
Save Article
Similar Reads
Related Tutorials