Calculate weight of parenthesis based on the given conditions

Given a valid parenthesis string S, the task is to find the weight of parenthesis based on the following conditions:

  1. Weight of “( )” is 1
  2. Weight of “AB” = weight of “A” + weight of “B” (where, A and B are both independent valid parenthesis). e.g. weight of “()()” = weight of “()” + weight of “()”
  3. Weight of “(A)” = 2 times weight of “A” (where, A is independent valid parenthesis). e.g. weight of “(())” is 2 times weight of “()”

Examples:

Input: S = “()(())”
Output: 3
Explanation:
Weight of () = 1
Weight of (()) = 2
Hence, weight of ()(()) = 1 + 2 = 3

Input: S = “(()(()))”
Output: 6
Explanation:
Weight of ()(()) = 3
Weight of (()(())) = 2 * 3 = 6

Approach:
This problem can be solved using Divide and Conquer approach. Follow the steps below to solve the problem:



  • It is given that the input parenthesis string is always valid i.e. balanced. So, any opening bracket ‘(‘ has a corresponding closing bracket ‘)’.
  • Consider the opening bracket at the beginning of the input string (The beginning bracket can not be a closing bracket, otherwise it will not be valid). Now, for this opening bracket, the corresponding closing bracket can have any of the following two possible indices.
    1. At the very end i.e. (n-1)th index
    2. Somewhere between start and end i.e. [1, n-2]
  • If the closing bracket has an index at the end, then according to constraint no. 3, the total weight of parenthesis will be twice that of the weight of string[1, n-2].
  • If the closing bracket is somewhere in between start and end, say mid, then according to constraint no. 2, the total weight of parenthesis will be the sum of the weight of string[start, mid] and the sum of the weight of string[mid+1, end].
  • The base case for our recursion will be when we have only two brackets in the string, they will have weight 1 because inherently they will be valid.
  • Now, the question is how we can find out the index of the corresponding closing bracket for an opening bracket. The idea is similar to Valid Parenthesis Check. We will use the Stack Data Structure to check and store the index of the closing bracket for the corresponding opening bracket in a HashMap.
  • Perform the following steps:

    • Traverse through the string.
    • If a character is an opening bracket, push its index into the Stack.
    • If it is a closing bracket, pop its index from the Stack and insert the (popped_index, current_index) pairing into the HashMap.

Below is the implementation of the above approach.

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to implement 
// the above approach 
#include <bits/stdc++.h>
using namespace std;
  
// HashMap to store the ending 
// index of every opening bracket 
unordered_map<int, int> endIndex; 
  
// Function to calculate and store 
// the closing index of each opening 
// bracket in the parenthesis 
void getClosingIndex(string s) 
    int n = s.length(); 
  
    stack<int> st; 
  
    for(int i = 0; i < n; i++) 
    
        if (s[i] == ')')
        
              
            // If it's a closing bracket, 
            // pop index of it's corresponding 
            // opening bracket 
            int startIndex = st.top(); 
            st.pop();
              
            // Insert the index of opening 
            // bracket and closing bracket 
            // as key-value pair in the 
            // hashmap 
            endIndex[startIndex] = i; 
        
        else
        
              
            // If it's an opening bracket, 
            // push it's index into the stack 
            st.push(i); 
        
    
  
// Function to return the weight of 
// parenthesis 
int calcWeight(string s, int low, int high) 
      
    // Base case 
    if (low + 1 == high)
    
        return 1; 
    
  
    else 
    
  
        // Mid refers to ending index of 
        // opening bracket at index low 
        int mid = endIndex[low]; 
          
        if (mid == high)
        
            return 2 * calcWeight(s, low + 1, 
                                    high - 1); 
        
        else
        
            return calcWeight(s, low, mid) + 
                   calcWeight(s, mid + 1, 
                              high); 
        
    
  
// Driver Code
int main()
{
    string input = "(()(()))"
    int n = input.length(); 
  
    // Update the closing Index 
    getClosingIndex(input); 
  
    cout << (calcWeight(input, 0, n - 1)) << endl; 
  
    return 0;
}
  
// This code is contributed by divyeshrabadiya07

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java Program to implement 
// the above approach 
import java.util.*; 
  
public class GFG { 
  
    // HashMap to store the ending 
    // index of every opening bracket 
    static HashMap<Integer, Integer> endIndex 
        = new HashMap<Integer, Integer>(); 
  
    // Function to calculate and store 
    // the closing index of each opening 
    // bracket in the parenthesis 
    public static void getClosingIndex(String s) 
    
  
        int n = s.length(); 
  
        Stack<Integer> st = new Stack<Integer>(); 
  
        for (int i = 0; i < n; i++) { 
  
            if (s.charAt(i) == ')') { 
  
                // If it's a closing bracket, 
                // pop index of it's corresponding 
                // opening bracket 
                int startIndex = st.pop(); 
  
                // Insert the index of opening 
                // bracket and closing bracket 
                // as key-value pair in the 
                // hashmap 
                endIndex.put(startIndex, i); 
            
            else
  
                // If it's an opening bracket, 
                // push it's index into the stack 
                st.push(i); 
            
        
    
  
    // Function to return the weight of 
    // parenthesis 
    public static int calcWeight(String s, 
                                int low, 
                                int high) 
    
  
        // Base case 
        if (low + 1 == high) { 
            return 1
        
  
        else
  
            // Mid refers to ending index of 
            // opening bracket at index low 
            int mid = endIndex.get(low); 
            if (mid == high) { 
                return 2 * calcWeight(s, low + 1
                                    high - 1); 
            
            else
                return calcWeight(s, low, mid) 
                    + calcWeight(s, mid + 1
                                high); 
            
        
    
  
    public static void main(String[] args) 
    
        String input = "(()(()))"
        int n = input.length(); 
  
        // Update the closing Index 
        getClosingIndex(input); 
  
        System.out.println(calcWeight(input, 
                                    0, n - 1)); 
    

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to implement the 
# above approach 
  
# Function to calculate and store 
# the closing index of each opening 
# bracket in the parenthesis 
def getClosingIndex(string): 
  
    # Dictionary to store 
    # the ending index of 
    # each opening bracket 
    endIndex = dict() 
  
  
    n = len(string) 
  
    stack = [] 
    for i in range(n): 
        if (string[i]==')'): 
  
            # If it's a closing bracket, 
            # pop index of it's 
            # corresponding 
            # opening bracket 
            startIndex = stack.pop() 
  
            # Put the index of opening 
            # bracket and closing 
            # bracket as key value 
            # pair in the Dictionary 
            endIndex[startIndex] =
  
        else
  
            # If it's an opening bracket, 
            # push it's index into 
            # the stack 
            stack.append(i) 
    return endIndex 
      
# Function to return the weight 
# of parenthesis 
def calcWeight(s, low, 
                high, endIndex): 
  
  
    # Base case 
    if (low + 1 == high): 
        return 1
    else
  
        # Mid refers to ending index of 
        # opening bracket at index low 
        mid = endIndex[low] 
        if (mid == high): 
            return 2*(calcWeight(s, low + 1
            high-1, endIndex)) 
  
        else
            return calcWeight(s, low, 
            mid, endIndex) + calcWeight(s, 
            mid + 1, high, endIndex) 
  
  
if __name__ == "__main__"
    string = "(()(()))"
    n = len(string) 
    endIndex = getClosingIndex(string) 
    print(calcWeight(string, 0
    n-1, endIndex)) 

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to implement
// the above approach
using System;
using System.Collections.Generic; 
  
class GFG{
  
// HashMap to store the ending
// index of every opening bracket
static Dictionary<int,
                  int> endIndex = new Dictionary<int,
                                                 int>();
  
// Function to calculate and store
// the closing index of each opening
// bracket in the parenthesis
public static void getClosingIndex(string s)
{
    int n = s.Length;
  
    Stack<int> st = new Stack<int>();
  
    for(int i = 0; i < n; i++)
    {
        if (s[i] == ')'
        {
              
            // If it's a closing bracket,
            // pop index of it's corresponding
            // opening bracket
            int startIndex = st.Pop();
  
            // Insert the index of opening
            // bracket and closing bracket
            // as key-value pair in the
            // hashmap
            endIndex.Add(startIndex, i);
        }
        else
        {
  
            // If it's an opening bracket,
            // push it's index into the stack
            st.Push(i);
        }
    }
}
  
// Function to return the weight of
// parenthesis
public static int calcWeight(string s, int low,
                                       int high)
{
  
    // Base case
    if (low + 1 == high)
    {
        return 1;
    }
    else 
    {
          
        // Mid refers to ending index of
        // opening bracket at index low
        int mid = endIndex[low];
        if (mid == high)
        {
            return 2 * calcWeight(s, low + 1,
                                    high - 1);
        }
        else
        {
            return calcWeight(s, low, mid) + 
                   calcWeight(s, mid + 1, high);
        }
    }
}
  
// Driver code
public static void Main(string[] args)
{
    string input = "(()(()))";
    int n = input.Length;
  
    // Update the closing Index
    getClosingIndex(input);
  
    Console.Write(calcWeight(input, 0, n - 1));
}
}
  
// This code is contributed by rutvik_56

chevron_right


Output:

6


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

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

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.