Split string into three palindromic substrings with earliest possible cuts

Given string str, the task is to check if it is possible to split the given string S into three palindromic substrings or not. If multiple answers are possible, then print the one where the cuts are made the least indices. If no such possible partition exists then print “-1”.

Examples:

Input: str = “aabbcdc”
Output: aa bb cdc
Explanation:
Only one possible partition exists {“aa”, “bb”, “cdc”}.

Input: str = “ababbcb”
Output: a bab bcb 
Explanation: Possible splits are {“aba”, “b”, “bcb”} and {“a”, “bab”, “bcb”}. 
Since, {“a”, “bab”, “bcb”} has splits at earlier indices, it is the required answer.

Approach: Follow the steps below to solve the problem:



  1. Generate all possible substrings of the string and check whether the given substring is palindromic or not.
  2. If any substring is present then store the last index of a substring in a vector startPal, where startPal will store the first palindrome starting from 0 indexes and ending at stored value.
  3. Similar to the first step, generate all the substring from the last index of the given string str and check whether the given substring is palindrome or not. If any substring is present as a substring then store the last index of a substring in the vector lastPal, where lastPal will store the third palindrome starting from stored value and ending at (N – 1)th index of the given string str.
  4. Reverse the vector lastPal to get the earliest cut.
  5. Now, iterate two nested loop, the outer loop picks the first palindrome ending index from the startPal and the inner loop picks the third palindrome starting index from the lastPal. If the value of startPal is lesser than the lastPal value then store it in the middlePal vector in form of pairs.
  6. Now traverse over the vector middlePal and check if the substring between the ending index of the first palindrome and staring index of the third palindrome is palindrome or not. If found to be true then the first palindrome = s.substr(0, middlePal[i].first), third palindrome = s.substr(middlePal[i].second, N – middlePal[i].second) and rest string will be third string.
  7. If all the three palindromic strings are present then print that string Otherwise print “-1”.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to check if a string
// is palindrome or not
bool isPalindrome(string x)
{
    // Copy the string x to y
    string y = x;
 
    // Reverse the string y
    reverse(y.begin(), y.end());
 
    if (x == y) {
 
        // If string x equals y
        return true;
    }
 
    return false;
}
 
// Function to find three palindromes
// from the given string with earliest
// possible cuts
void Palindromes(string S, int N)
{
    // Stores index of palindrome
    // starting from left & right
    vector<int> startPal, lastPal;
 
    string start;
 
    // Store the indices for possible
    // palindromes from left
    for (int i = 0;
         i < S.length() - 2; i++) {
 
        // Push the current character
        start.push_back(S[i]);
 
        // Check for palindrome
        if (isPalindrome(start)) {
 
            // Insert the current index
            startPal.push_back(i);
        }
    }
 
    string last;
 
    // Stores the indexes for possible
    // palindromes from right
    for (int j = S.length() - 1;
         j >= 2; j--) {
 
        // Push the current character
        last.push_back(S[j]);
 
        // Check palindromic
        if (isPalindrome(last)) {
 
            // Insert the current index
            lastPal.push_back(j);
        }
    }
 
    // Sort the indexes for palindromes
    // from right in ascending order
    reverse(lastPal.begin(),
            lastPal.end());
 
    vector<pair<int, int> > middlePal;
 
    for (int i = 0;
         i < startPal.size(); i++) {
 
        for (int j = 0;
             j < lastPal.size(); j++) {
 
            // If the value of startPal
            // < lastPal value then
            // store it in middlePal
            if (startPal[i] < lastPal[j]) {
 
                // Insert the current pair
                middlePal.push_back(
                    { startPal[i],
                      lastPal[j] });
            }
        }
    }
 
    string res1, res2, res3;
    int flag = 0;
 
    // Traverse over the middlePal
    for (int i = 0;
         i < middlePal.size(); i++) {
 
        int x = middlePal[i].first;
        int y = middlePal[i].second;
 
        string middle;
 
        for (int k = x + 1; k < y; k++) {
            middle.push_back(S[k]);
        }
 
        // Check if the middle part
        // is palindrome
        if (isPalindrome(middle)) {
            flag = 1;
            res1 = S.substr(0, x + 1);
            res2 = middle;
            res3 = S.substr(y, N - y);
            break;
        }
    }
 
    // Print the three palindromic
    if (flag == 1) {
        cout << res1 << " "
             << res2 << " "
             << res3;
    }
 
    // Otherwise
    else
        cout << "-1";
}
 
// Driver Code
int main()
{
    // Given string str
    string str = "ababbcb";
 
    int N = str.length();
 
    // Function Call
    Palindromes(str, N);
 
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program for the
// above approach
import java.util.*;
class GFG{
 
static class pair
{
  int first, second;
  public pair(int first,
              int second)
  {
    this.first = first;
    this.second = second;
  }
}
 
static String reverse(String input)
{
  char[] a = input.toCharArray();
  int l, r = a.length - 1;
   
  for (l = 0; l < r; l++, r--)
  {
    char temp = a[l];
    a[l] = a[r];
    a[r] = temp;
  }
  return String.valueOf(a);
}
 
// Function to check if a String
// is palindrome or not
static boolean isPalindrome(String x)
{
  // Copy the String x to y
  String y = x;
 
  // Reverse the String y
  y = reverse(y);
 
  if (x.equals(y))
  {
    // If String x equals y
    return true;
  }
 
  return false;
}
 
// Function to find three palindromes
// from the given String with earliest
// possible cuts
static void Palindromes(String S,
                        int N)
{
  // Stores index of palindrome
  // starting from left & right
  Vector<Integer> startPal =
         new Vector<>();
  Vector<Integer> lastPal =
         new Vector<>();
 
  String start = "";
 
  // Store the indices for possible
  // palindromes from left
  for (int i = 0;
           i < S.length() - 2; i++)
  {
    // Push the current character
    start += S.charAt(i);
 
    // Check for palindrome
    if (isPalindrome(start))
    {
      // Insert the current index
      startPal.add(i);
    }
  }
 
  String last = "";
 
  // Stores the indexes for possible
  // palindromes from right
  for (int j = S.length() - 1;
           j >= 2; j--)
  {
    // Push the current character
    last += S.charAt(j);
 
    // Check palindromic
    if (isPalindrome(last))
    {
      // Insert the current index
      lastPal.add(j);
    }
  }
 
  // Sort the indexes for palindromes
  // from right in ascending order
  Collections.reverse(lastPal);
 
  Vector<pair> middlePal =
               new Vector<>();
   
  for (int i = 0;
           i < startPal.size(); i++)
  {
    for (int j = 0;
             j < lastPal.size(); j++)
    {
      // If the value of startPal
      // < lastPal value then
      // store it in middlePal
      if (startPal.get(i) <
          lastPal.get(j))
      {
        // Insert the current pair
        middlePal.add(new pair(startPal.get(i),
                               lastPal.get(j)));
      }
    }
  }
 
  String res1 = "",
         res2 = "", res3 = "";
  int flag = 0;
 
  // Traverse over the middlePal
  for (int i = 0;
           i < middlePal.size(); i++)
  {
    int x = middlePal.get(i).first;
    int y = middlePal.get(i).second;
    String middle = "";
 
    for (int k = x + 1; k < y; k++)
    {
      middle += S.charAt(k);
    }
 
    // Check if the middle part
    // is palindrome
    if (isPalindrome(middle))
    {
      flag = 1;
      res1 = S.substring(0, x + 1);
      res2 = middle;
      res3 = S.substring(y, N);
      break;
    }
  }
 
  // Print the three palindromic
  if (flag == 1)
  {
    System.out.print(res1 + " " +
                     res2 + " " + res3);
  }
 
  // Otherwise
  else
    System.out.print("-1");
}
 
// Driver Code
public static void main(String[] args)
{
  // Given String str
  String str = "ababbcb";
 
  int N = str.length();
 
  // Function Call
  Palindromes(str, N);
}
}
 
// This code is contributed by shikhasingrajput

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program for the above approach
 
# Function to check if a strring
# is palindrome or not
def isPalindrome(x):
     
    # Copy the x to y
    y = x
 
    # Reverse the y
    y = y[::-1]
 
    if (x == y):
 
        # If x equals y
        return True
         
    return False
 
# Function to find three palindromes
# from the given with earliest
# possible cuts
def Palindromes(S, N):
     
    # Stores index of palindrome
    # starting from left & right
    startPal, lastPal = [], []
 
    start = []
 
    # Store the indices for possible
    # palindromes from left
    for i in range(len(S) - 2):
 
        # Push the current character
        start.append(S[i])
 
        # Check for palindrome
        if (isPalindrome(start)):
 
            # Insert the current index
            startPal.append(i)
 
    last = []
 
    # Stores the indexes for possible
    # palindromes from right
    for j in range(len(S) - 1, 1, -1):
 
        # Push the current character
        last.append(S[j])
 
        # Check palindromic
        if (isPalindrome(last)):
 
            # Insert the current index
            lastPal.append(j)
 
    # Sort the indexes for palindromes
    # from right in ascending order
    lastPal = lastPal[::-1]
 
    middlePal = []
 
    for i in range(len(startPal)):
        for j in range(len(lastPal)):
 
            # If the value of startPal
            # < lastPal value then
            # store it in middlePal
            if (startPal[i] < lastPal[j]):
 
                # Insert the current pair
                middlePal.append([startPal[i],
                                   lastPal[j]])
 
    res1, res2, res3 = "", "", ""
    flag = 0
 
    # Traverse over the middlePal
    for i in range(len(middlePal)):
        x = middlePal[i][0]
        y = middlePal[i][1]
        #print(x,y)
 
        middle = ""
 
        for k in range(x + 1, y):
            middle += (S[k])
 
        # Check if the middle part
        # is palindrome
        if (isPalindrome(middle)):
            flag = 1
            res1 = S[0 : x + 1]
            res2 = middle
            res3 = S[y : N]
            #print(S,x,y,N)
            break
 
    # Print the three palindromic
    if (flag == 1):
        print(res1, res2, res3)
 
    # Otherwise
    else:
        print("-1")
 
# Driver Code
if __name__ == '__main__':
     
    # Given strr
    strr = "ababbcb"
 
    N = len(strr)
 
    # Function call
    Palindromes(strr, N)
 
# This code is contributed by mohit kumar 29

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program for the
// above approach
using System;
using System.Collections.Generic;
 
class GFG{
 
public class pair
{
  public int first, second;
  public pair(int first,
              int second)
  {
    this.first = first;
    this.second = second;
  }
}
 
static String reverse(String input)
{
  char[] a = input.ToCharArray();
  int l, r = a.Length - 1;
   
  for(l = 0; l < r; l++, r--)
  {
    char temp = a[l];
    a[l] = a[r];
    a[r] = temp;
  }
  return String.Join("",a);
}
 
// Function to check if a String
// is palindrome or not
static bool isPalindrome(String x)
{
   
  // Copy the String x to y
  String y = x;
 
  // Reverse the String y
  y = reverse(y);
 
  if (x.Equals(y))
  {
     
    // If String x equals y
    return true;
  }
  return false;
}
 
// Function to find three palindromes
// from the given String with earliest
// possible cuts
static void Palindromes(String S,
                        int N)
{
   
  // Stores index of palindrome
  // starting from left & right
  List<int> startPal = new List<int>();
  List<int> lastPal = new List<int>();
   
  String start = "";
 
  // Store the indices for possible
  // palindromes from left
  for(int i = 0;
          i < S.Length - 2; i++)
  {
     
    // Push the current character
    start += S[i];
 
    // Check for palindrome
    if (isPalindrome(start))
    {
       
      // Insert the current index
      startPal.Add(i);
    }
  }
 
  String last = "";
 
  // Stores the indexes for possible
  // palindromes from right
  for(int j = S.Length - 1;
          j >= 2; j--)
  {
     
    // Push the current character
    last += S[j];
 
    // Check palindromic
    if (isPalindrome(last))
    {
       
      // Insert the current index
      lastPal.Add(j);
    }
  }
   
  // Sort the indexes for palindromes
  // from right in ascending order
  lastPal.Reverse();
 
  List<pair> middlePal = new List<pair>();
   
  for(int i = 0;
          i < startPal.Count; i++)
  {
    for(int j = 0;
            j < lastPal.Count; j++)
    {
       
      // If the value of startPal
      // < lastPal value then
      // store it in middlePal
      if (startPal[i] < lastPal[j])
      {
         
        // Insert the current pair
        middlePal.Add(new pair(startPal[i],
                                lastPal[j]));
      }
    }
  }
 
  String res1 = "", res2 = "",
         res3 = "";
  int flag = 0;
 
  // Traverse over the middlePal
  for(int i = 0;
          i < middlePal.Count; i++)
  {
    int x = middlePal[i].first;
    int y = middlePal[i].second;
    String middle = "";
 
    for(int k = x + 1; k < y; k++)
    {
      middle += S[k];
    }
 
    // Check if the middle part
    // is palindrome
    if (isPalindrome(middle))
    {
      flag = 1;
      res1 = S.Substring(0, x + 1);
      res2 = middle;
      res3 = S.Substring(y);
      break;
    }
  }
 
  // Print the three palindromic
  if (flag == 1)
  {
    Console.Write(res1 + " " +
                  res2 + " " + res3);
  }
 
  // Otherwise
  else
    Console.Write("-1");
}
 
// Driver Code
public static void Main(String[] args)
{
   
  // Given String str
  String str = "ababbcb";
 
  int N = str.Length;
 
  // Function Call
  Palindromes(str, N);
}
}
 
// This code is contributed by Amit Katiyar

chevron_right


Output: 

a bab bcb






 

Time Complexity: O(N2)
Auxiliary Space: O(N)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up

Recommended Posts:


Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.