In this tutorial we will take a look at a problem which falls under the general category of algorithmic problems without the need of a particular design technique to get a good solution.

Problem

We are given a string of parenthesis and we want to find the maximal length of substrings. For example, for the string “())(())” the maximal length is 4 and comes from the substring “(())”.

Algorithm Analysis

We will calculate the maximal length of valid parentheses by matching closing parenthesis with opening parenthesis.

We are utilizing a stack to hold the indexes of parentheses. The first index indicates where the current string of parentheses starts. If the first index is k and the last index is m, then the string currently in the stack is the string from k+1 to m (the first index is not in the string).

The algorithm then is as follows:

We iterate through the given string of parentheses:
If we encounter an opening parenthesis, we push it on the stack.
If we encounter a closing parenthesis, we do the following:
   We check if the stack is empty:

     -If not, we have found a valid substring.
     We check if it is the max found yet.
     To do that, we need to find its length.
     The length of the current substring
     is the difference between the current index
     and the last index in the stack
     (since the valid string is between those two indexes).
     If that is larger than the maximum length
     we have found previously, we update it.

     -If the stack is empty,
     we push the current index on its top. The next (possible)
     valid string begins after it.

If we encounter a character other than '(' or ')', we return -1.

The final value of maxLength is the solution.

Complexity Analysis

* Iterating over the given index: O(n), since we are making one linear pass.
* Pushing and popping are O(1).
* The rest are O(1) calculations.

* Thus the algorithm is O(n). ( because O(n)*O(1)*O(1) = O(n) )
* Since the algorithm is O(n) and for a solution we have to read the whole string, which takes O(n), the algorithm is optimal.

Code

def FindLength(par):
    parLength = len(par);
    maxLength = 0;
    stack = [-1];
    
    for i in range(parLength):
        p = par[i];
        if(p == '('):
            #Add index to stack
            stack.append(i);
        elif(p == ')'):
            stack.pop(); #Pop top item
            stackLength = len(stack);
            if(stackLength > 0):
                #Stack is not empty, calculate maxLength
                lastIndex = stack[-1];
                if(i-lastIndex > maxLength):
                    maxLength = i-lastIndex;
            else:
                #Stack is empty, set it to current index
                stack = [i]
        else:
            #Encountered char other than parentheses
            return -1;

    return maxLength;

For testing:

par = "()(())";
print FindLength(par);
par = "(((()()))";
print FindLength(par);

You can also find the code on my GitHub. Thanks for dropping by.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s