Open In App
Related Articles

Reverse substrings between each pair of parenthesis

Improve
Improve
Improve
Like Article
Like
Save Article
Save
Report issue
Report

Given a string str that consists of lowercase English letters and brackets. The task is to reverse the substrings in each pair of matching parentheses, starting from the innermost one. The result should not contain any brackets.

Examples:  

Input: str = “(skeeg(for)skeeg)” 
Output: geeksforgeeks

Input: str = “((ng)ipm(ca))” 
Output: camping 

Approach: This problem can be solved using a stack. First, whenever a ‘(‘ is encountered then push the index of the element into the stack, and whenever a ‘)’ is encountered then get the top element of the stack as the latest index and reverse the string between the current index and index from the top of the stack. Follow this for the rest of the string and finally print the updated string.

Below is the implementation of the above approach:  

C++

// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to return the modified string
string reverseParentheses(string str, int len)
{
    stack<int> st;
 
    for (int i = 0; i < len; i++) {
 
        // Push the index of the current
        // opening bracket
        if (str[i] == '(') {
            st.push(i);
        }
 
        // Reverse the substring starting
        // after the last encountered opening
        // bracket till the current character
        else if (str[i] == ')') {
            reverse(str.begin() + st.top() + 1,
                    str.begin() + i);
            st.pop();
        }
    }
 
    // To store the modified string
    string res = "";
    for (int i = 0; i < len; i++) {
        if (str[i] != ')' && str[i] != '(')
            res += (str[i]);
    }
    return res;
}
 
// Driver code
int main()
{
    string str = "(skeeg(for)skeeg)";
    int len = str.length();
 
    cout << reverseParentheses(str, len);
 
    return 0;
}

                    

Java

// Java implementation of the approach
import java.io.*;
import java.util.*;
class GFG {
  static void reverse(char A[], int l, int h)
  {
    if (l < h)
    {
      char ch = A[l];
      A[l] = A[h];
      A[h] = ch;
      reverse(A, l + 1, h - 1);
    }
  }
   
  // Function to return the modified string
  static String reverseParentheses(String str, int len)
  {
    Stack<Integer> st = new Stack<Integer>();
    for (int i = 0; i < len; i++)
    {
       
      // Push the index of the current
      // opening bracket
      if (str.charAt(i) == '(')
      {
        st.push(i);
      }
       
      // Reverse the substring starting
      // after the last encountered opening
      // bracket till the current character
      else if (str.charAt(i) == ')')
      {
        char[] A = str.toCharArray();
        reverse(A, st.peek() + 1, i);
        str = String.copyValueOf(A);
        st.pop();
      }
    }
     
    // To store the modified string
    String res = "";
    for (int i = 0; i < len; i++)
    {
      if (str.charAt(i) != ')' && str.charAt(i) != '(')
      {
        res += (str.charAt(i));
      }
    }
    return res;
  }
 
  // Driver code
  public static void main (String[] args)
  {
    String str = "(skeeg(for)skeeg)";
    int len = str.length();
    System.out.println(reverseParentheses(str, len));
  }
}
 
// This code is contributed by avanitrachhadiya2155

                    

Python3

# Python3 implementation of the approach
 
# Function to return the modified string
def reverseParentheses(strr, lenn):
    st = []
 
    for i in range(lenn):
 
        # Push the index of the current
        # opening bracket
        if (strr[i] == '('):
            st.append(i)
 
        # Reverse the substring starting
        # after the last encountered opening
        # bracket till the current character
        else if (strr[i] == ')'):
            temp = strr[st[-1]:i + 1]
            strr = strr[:st[-1]] + temp[::-1] + \
                   strr[i + 1:]
            del st[-1]
 
    # To store the modified string
    res = ""
    for i in range(lenn):
        if (strr[i] != ')' and strr[i] != '('):
            res += (strr[i])
    return res
 
# Driver code
if __name__ == '__main__':
    strr = "(skeeg(for)skeeg)"
    lenn = len(strr)
    st = [i for i in strr]
 
    print(reverseParentheses(strr, lenn))
 
# This code is contributed by Mohit Kumar

                    

C#

// C# implementation of the approach
using System;
using System.Collections.Generic;
using System.Text;
 
class GFG{
     
static void reverse(char[] A, int l, int h)
{
    if (l < h)
    {
        char ch = A[l];
        A[l] = A[h];
        A[h] = ch;
        reverse(A, l + 1, h - 1);
    }
}
 
// Function to return the modified string
static string reverseParentheses(string str, int len)
{
    Stack<int> st = new Stack<int>();
     
    for(int i = 0; i < len; i++)
    {
         
        // Push the index of the current
        // opening bracket
        if (str[i] == '(')
        {
            st.Push(i);
        }
         
        // Reverse the substring starting
        // after the last encountered opening
        // bracket till the current character
        else if (str[i] == ')')
        {
            char[] A = str.ToCharArray();
            reverse(A, st.Peek() + 1, i);
            str = new string(A);
            st.Pop();
        }
    }
     
    // To store the modified string
    string res = "";
    for(int i = 0; i < len; i++)
    {
        if (str[i] != ')' && str[i] != '(')
        {
            res += str[i];
        }
    }
    return res;
}
 
// Driver code
static public void Main()
{
    string str = "(skeeg(for)skeeg)";
    int len = str.Length;
     
    Console.WriteLine(reverseParentheses(str, len));
}
}
 
// This code is contributed by rag2127

                    

Javascript

<script>
// Javascript implementation of the approach
function reverse(A,l,h)
{
    if (l < h)
    {
      let ch = A[l];
      A[l] = A[h];
      A[h] = ch;
      reverse(A, l + 1, h - 1);
    }
}
 
 // Function to return the modified string
function reverseParentheses(str,len)
{
    let st = [];
    for (let i = 0; i < len; i++)
    {
        
      // Push the index of the current
      // opening bracket
      if (str[i] == '(')
      {
        st.push(i);
      }
        
      // Reverse the substring starting
      // after the last encountered opening
      // bracket till the current character
      else if (str[i] == ')')
      {
           
        let A = [...str]
        reverse(A, st[st.length-1] + 1, i);
        str = [...A];
        st.pop();
      }
    }
      
    // To store the modified string
    let res = "";
    for (let i = 0; i < len; i++)
    {
      if (str[i] != ')' && str[i] != '(')
      {
        res += (str[i]);
      }
    }
    return res;
}
 
 // Driver code
let str = "(skeeg(for)skeeg)";
let len = str.length;
document.write(reverseParentheses(str, len));
 
// This code is contributed by patel2127
</script>

                    

Output
geeksforgeeks






Time Complexity: O(n2), where n is the length of the given string.
Auxiliary Space: O(n)

Efficient Approach:

Our Approach is simple and we can reduce the space complexity from O(n) to O(1) that is constant space .

Approach:

We create a function for reversing substrings between the opening and closing brackets one by one, beginning with the innermost one. We can use a while loop to keep doing this until we run out of brackets.

In each iteration of the while loop, we first find the index of the string’s initial closing bracket. We exit the loop if there is no closing bracket. Otherwise, we search backwards from the closing bracket to identify the appropriate starting bracket.

The reverseSubstring function is then used to reverse the substring between the opening and closing brackets. Finally, we use the erase function to delete the opening and closing brackets from the string.

Implementation:

C++

#include <bits/stdc++.h>
using namespace std;
 
string reverseSubstring(string str, int start, int end) {
   reverse(str.begin()+start, str.begin()+end+1);
   return str;
}
 
string reverseParentheses(string str) {
   int n = str.length();
   int start, end;
 
   while (true) {
       // find the first closing bracket
       end = str.find(')', 0);
       if (end == string::npos) {
           break; // no more closing brackets, we're done
       }
 
       // find the corresponding opening bracket
       start = str.rfind('(', end);
 
       // reverse the substring between the opening and closing brackets
       str = reverseSubstring(str, start+1, end-1);
 
       // remove the opening and closing brackets
       str.erase(start, 1);
       str.erase(end-1, 1);
   }
 
   return str;
}
 
int main() {
   string str="(skeeg(for)skeeg)";
   cout<<reverseParentheses(str)<<endl;
   return 0;
}

                    

Java

import java.util.Stack;
 
public class GFG {
 
    static String ReverseSubstring(String str, int start,
                                   int end)
    {
        StringBuilder reversed = new StringBuilder();
        for (int i = end; i >= start; i--) {
            reversed.append(str.charAt(i));
        }
        return str.substring(0, start) + reversed.toString()
            + str.substring(end + 1);
    }
 
    static String ReverseParentheses(String str)
    {
        int start, end;
        while (true) {
            // find the first closing bracket
            end = str.indexOf(')');
            if (end == -1) {
                break; // no more closing brackets, we're
                       // done
            }
 
            // find the corresponding opening bracket
            start = str.lastIndexOf('(', end);
 
            // reverse the substring between the opening and
            // closing brackets
            str = ReverseSubstring(str, start + 1, end - 1);
 
            // remove the opening and closing brackets
            str = str.substring(0, start)
                  + str.substring(start + 1, end)
                  + str.substring(end + 1);
        }
        return str;
    }
 
    public static void main(String[] args)
    {
        String str = "(skeeg(for)skeeg)";
        System.out.println(ReverseParentheses(str));
    }
}

                    

Python3

def reverse_substring(s, start, end):
    return s[:start] + s[start:end+1][::-1] + s[end+1:]
 
def reverse_parentheses(s):
    while True:
        end = s.find(')')
        if end == -1:
            break
 
        start = s.rfind('(', 0, end)
        s = reverse_substring(s, start+1, end-1)
        s = s[:start] + s[start+1:]
        s = s[:end-1] + s[end:]
 
    return s
 
if __name__ == "__main__":
    s = "(skeeg(for)skeeg)"
    print(reverse_parentheses(s))

                    

C#

using System;
using System.Text;
 
class Program
{
    static string ReverseSubstring(string str, int start, int end)
    {
        StringBuilder reversed = new StringBuilder();
        for (int i = end; i >= start; i--)
        {
            reversed.Append(str[i]);
        }
        return str.Substring(0, start) + reversed.ToString() + str.Substring(end + 1);
    }
 
    static string ReverseParentheses(string str)
    {
        int start, end;
        while (true)
        {
            // find the first closing bracket
            end = str.IndexOf(')');
            if (end == -1)
            {
                break; // no more closing brackets, we're done
            }
 
            // find the corresponding opening bracket
            start = str.LastIndexOf('(', end);
 
            // reverse the substring between the opening and closing brackets
            str = ReverseSubstring(str, start + 1, end - 1);
 
            // remove the opening and closing brackets
            str = str.Substring(0, start) + str.Substring(start + 1, end - start - 1) + str.Substring(end + 1);
        }
        return str;
    }
 
    static void Main(string[] args)
    {
        string str = "(skeeg(for)skeeg)";
        Console.WriteLine(ReverseParentheses(str));
    }
}

                    

Javascript

function reverseSubstring(str, start, end) {
   return str.slice(0, start) +
          str.slice(start, end+1).split('').reverse().join('') +
          str.slice(end+1);
}
 
function reverseParentheses(str) {
   let start, end;
   while (true) {
       // find the first closing bracket
       end = str.indexOf(')');
       if (end === -1) {
           break; // no more closing brackets, we're done
       }
        
       // find the corresponding opening bracket
       start = str.lastIndexOf('(', end);
        
       // reverse the substring between the opening and closing brackets
       str = reverseSubstring(str, start+1, end-1);
        
       // remove the opening and closing brackets
       str = str.slice(0, start) + str.slice(start+1, end) + str.slice(end+1);
   }
   return str;
}
 
let str = "(skeeg(for)skeeg)";
console.log(reverseParentheses(str));

                    

Output
geeksforgeeks



Time Complexity: O(n^2), where n is the length of the given string.

Auxiliary Space: O(1),No extra space is used.



Last Updated : 18 Oct, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads