Split Parenthesis Sequence into maximum valid Substrings


In this problem, we need to split the parenthesis string into valid groups. When all opening brackets have related closing brackets, we can say that the group of parenthesis is valid.

Problem Statement

We have given a string containing open and closed parentheses. We need to split the string to get the maximum valid parenthesis string.

Sample Examples

Input: par = "(())()(()())"
Output: (()), (), (()()),

Explanation

Each substring contains the valid parentheses sequence.

Input: par = "()()"
Output: (), ()

Explanation

We have splited the string into two groups.

Input: par = "()(())"
Output: (), (())

Approach 1

We will traverse the string, and if at any index number of open and closed parentheses are the same, we will print the previous substring and start a new one.

Algorithm

  • Step 1 − Initialize the 'open' and 'close' with 0 to store the number of open and closed brackets till the particular index. Also, define the list of strings to store the valid groups.

  • Step 2 − Return an empty list if the string length is 0.

  • Step 3 − Traverse the given string.

  • Step 4 − Append the current character to the 'temp' string.

  • Step 5 − If the current character is '(', increment open by 1. Otherwise, increment close by 1.

  • Step 6 − If the value of open and close is same, push the temp string to the 'ans' list.

  • Step 7 − Return the 'ans' list.

  • Step 8 − In the main() method, traverse the list of valid sequences, and print all sequences.

Example

Following are the examples to the above algorithm −

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Function to get balanced groups
char** getBalancedGroups(char* par) {
   char** ans = NULL;
   int open = 0;
   int close = 0;
   char* temp = NULL;
   int len = strlen(par);

   // To store the result
   int ansSize = 0;

   // Return NULL if the string is empty
   if (len == 0)
      return ans;

   // Allocate memory for the result array
   ans = (char**)malloc(sizeof(char*) * len);

   // Initialize temporary string
   temp = (char*)malloc(sizeof(char) * (len + 1));
   temp[0] = '\0';

   for (int p = 0; p < len; p++) {
      // Append the current character to the temporary string
      strncat(temp, &par[p], 1);

      // For opening braces
      if (par[p] == '(') {
         open++;
      }
      // For closing braces
      if (par[p] == ')') {
         close++;
      }

      // When we get a valid group, push it to the 'ans' list.
      if (open == close) {
         ans[ansSize] = (char*)malloc(sizeof(char) * (p + 2));
         strcpy(ans[ansSize], temp);
         ansSize++;
         temp[0] = '\0'; // Reset the temporary string
       }
   }

   // Resize the result array
   ans = (char**)realloc(ans, sizeof(char*) * ansSize);
   ans[ansSize] = NULL;

   free(temp); // Free the temporary string

   return ans;
}
int main() {
    char par[] = "(())()(()())";
    char** balancedGroup = getBalancedGroups(par);
    printf("The valid groups of parenthesis are - ");
    for (int i = 0; balancedGroup[i] != NULL; i++) {
        printf("%s, ", balancedGroup[i]);
        free(balancedGroup[i]); // Free memory used by each valid group
    }
    free(balancedGroup); // Free memory used by the result array
    return 0;
}

Output

The valid groups of parenthesis are - (()), (), (()()), 
#include <bits/stdc++.h>
using namespace std;

vector<string> getBalancedGroups(string par) {
   vector<string> ans;
   // To store a number of open and closed brackets
   int open = 0;
   int close = 0;
   // To store a valid group of parenthesis
   string temp = "";
   int len = par.size();
   // Return the same string if it is empty
   if (len == 0)
     return ans;

   // Finding valid groups
   for (int p = 0; p < len; p++) {
      temp += par[p];
      // For opening braces
      if (par[p] == '(') {
         open++;
      }
      // For closing braces
      if (par[p] == ')') {
         close++;
      }
      // When we get a valid group, push it to the 'ans' list.
      if (open == close) {
        ans.push_back(temp);
        temp = "";
      }
   }
   return ans;
}

int main() {
   string par = "(())()(()())";
   vector<string> balancedGroup;
   balancedGroup = getBalancedGroups(par);
   cout << "The valid groups of parenthesis are - ";
   // printing the balanced groups
   for (auto group : balancedGroup)
     cout << group << ", ";
   return 0;
}

Output

The valid groups of parenthesis are - (()), (), (()()), 
import java.util.ArrayList;
import java.util.List;

public class BalancedGroups {
   public static List<String> getBalancedGroups(String par) {
      List<String> ans = new ArrayList<>(); // Initialize the result list
      int open = 0;
      int close = 0;
      StringBuilder temp = new StringBuilder();
      int len = par.length(); // Calculate the length of the input string

      if (len == 0) {
         return ans;
      }

      for (int p = 0; p < len; p++) {
         temp.append(par.charAt(p)); // Append the current character to the temporary string
         if (par.charAt(p) == '(') {
            open++; // Increment the open bracket count
         } else if (par.charAt(p) == ')') {
            close++; // Increment the close bracket count
         }

         if (open == close) { // If the counts are equal, it's a valid group
            ans.add(temp.toString()); // Add the temporary string to the result list
            temp.setLength(0); // Reset the temporary string
         }
      }

      return ans; 
   }

   public static void main(String[] args) {
      String par = "(())()(()())"; 
      List<String> balancedGroup = getBalancedGroups(par); // Get balanced groups
      System.out.print("The valid groups of parenthesis are - ");
      for (String group : balancedGroup) {
         System.out.print(group + ", "); 
      }
   }
}

Output

The valid groups of parenthesis are - (()), (), (()()), 
def getBalancedGroups(par):
   ans = [] # Initialize the result list
   open = 0
   close = 0
   temp = ""
   len_par = len(par) # Calculate the length of the input string

   if len_par == 0:
      return ans

   for p in range(len_par):
      temp += par[p] # Append the current character to the temporary string
      if par[p] == '(':
         open += 1 # Increment the open bracket count
      elif par[p] == ')':
         close += 1 

      if open == close: # If the counts are equal, it's a valid group
         ans.append(temp) # Add the temporary string to the result list
         temp = "" 

   return ans 

if __name__ == "__main__":
   par = "(())()(()())"
   balancedGroup = getBalancedGroups(par) # Get balanced groups
   print("The valid groups of parenthesis are -", ", ".join(balancedGroup)) # Print the valid groups

Output

The valid groups of parenthesis are - (()), (), (()()), 

Time complexity − O(N) to traverse the string.

Space complexity − O(N) to store the valid subsequences.

We learned to find the valid sequences of parenthesis in this problem. We use the logic that when each open parenthesis has a related close parenthesis, we can say it is a valid subsequence and split the string.

Updated on: 27-Oct-2023

68 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements