Valid Parentheses
This article talks about a problem famously known as Valid Parentheses. True to its name the problem deals with finding whether a given string has valid set of parentheses. If you have been around mathematics or vice-versa 😝, then you already know what does valid parentheses mean and the importance of it. For full blown solutions you can always refer LeetCode. This article intends to just “Spot the Differences”. 🐮🐶
Problem 1
Given a string containing characters '('
and ')'
determine if the input string is valid. An input string is valid if, each opening bracket has a corresponding closing bracket.
> Let’s first analyze what is a valid string.
It’s always a good practice to think about the problem before jumping on to the solution. Let’s take some examples:
Valid:
()()()
(())()
((8)()8)
(((())))Invalid:
()(()
())(
Approach 1: Using a counter
As you might have noticed a parentheses string is valid if there is a closing bracket for every opening bracket. Also, the closing bracket should always come after the opening bracket.
This algorithm is simple:
- Initialize a
counter
= 0. - With every opening bracket we
increment
thecounter
by 1. - With every closing bracket we
decrement
thecounter
by 1. - If at any point
counter
< 0, this would mean we have encountered more closing brackets than the opening ones. Hence, invalid string. - If in the end
counter
> 0, this would mean some opening brackets don’t have their counter closing counterparts. Hence, the string is invalid. - Otherwise, the string is valid.
Approach 2: Using a Stack
Imagine you are given some plates one by one and you are asked to stack those plates. After all, stack
in data structures is analogous to a stack
of plates 🙃. The plates you are given are either red in color or blue. But there is a nice twist to this exercise, whenever you encounter a red plate you have to remove the top most blue plate.
If we follow this guideline red plate is never on the stack. Rather everytime a red plate is encountered it takes out one of the blue plates from the stack.
This is exactly what we do in this algorithm. Let’s look at the steps:
- Iterate the given string.
- If we encounter an opening bracket i.e.
'('
, push it onto the stack. - If we encounter a closing bracket i.e.
')'
, then check the element on the top of the stack. If the top element is'('
then pop the top element. Else, the string is invalid. - In the end if the stack is empty then the given string is valid, otherwise its invalid.
Note, we use a stack for this problem because a stack has the property that the last
element pushed onto the stack is the first
element to be popped. This property helps to ensure when we are finding the closest opening
bracket for a closing
bracket it will always be on the top of the stack.
A string can be valid if inside every pair of opening
and closing
brackets lies a valid string of parentheses. Thus, a {substring
} within a string is resolved first and then the its enclosing brackets are matched and removed. Just like the matching
plates 🤓. We will talk about the stack based approach in detail for Problem 2, so jump on to the next problem.
Problem 2
Given a string containing just the characters '('
, ')'
, '{'
, '}'
, '['
and ']'
, determine if the input string is valid.
An input string is valid if:
- Open brackets must be closed by the same type of brackets.
- Open brackets must be closed in the correct order.
Approach 1: Using a counter/counters
This approach doesn’t work for Problem 2.
Let’s look into the reason.
According to the counter based approach, whenever we encounter any of the opening
brackets i.e. '('
, '{'
, '[',
we increment the counter by 1 and whenever we encounter a closing
bracket i.e. ')'
, '}'
, ']'
we decrement the counter by 1.
The issue with this approach is that we might end up closing a round
bracket with a curly
bracket and still call the string as valid.
What you might be thinking is that there are three
kinds brackets, may be we need three
counters? One for each type, right? This would ensure sure the same kind of brackets
are always valid if only compared with their own kind. But what about the relative order.
For e.g. in the string (({))}
, if the round
brackets are separated from the curly
brackets, the round brackets in isolation would form a valid string i.e. (())
. Also the curly brackets would form a valid string of {}
. But, when they are together in the string (({))}
it becomes invalid. Thus it’s important to account for the relative ordering of the brackets
.
Approach 2: Using a Stack
Let’s talk about the relative order between brackets to understand how stack can be helpful especially when the brackets are of more than one kind.
Let’s repeat what we analyzed before, a string can be valid if inside every pair of opening
and closing
brackets lies a valid string of parentheses.
Thus, from the diagram above we can say a string is valid, if every opening bracket is followed by its closing bracket but only after a valid a substring.
As discussed in the diagram above, any closing bracket is matched to its nearest unmatched opening bracket on the left.
What if we remove an opening bracket on the left whenever a closing bracket is encountered.
Imagine a scenario where the given string is {(()()}}
. By the time we are looking at the closing bracket which is at index 6, the brackets between 2–5 index would have already been matched and hence cleared way for the next match. Thus, a closing bracket would always find its opening bracket on the top of stack.
The steps are pretty similar to what we had for Problem 1.
The only difference is that for Problem 2 we also need to consider the
kind
of the bracket.
- Iterate the given string.
- If we encounter an opening bracket i.e.
'(', '{' or '['
, push it onto the stack. - If we encounter a closing bracket i.e.
')', '}' or ']'
, then check the element on the top of the stack. If the top element is thematching
opening bracket, then pop the top element. Else, the string is invalid. - In the end if the stack is empty then the given string is valid, otherwise its invalid.
Hey ! if you liked the article, hit the clap 👏 button multiple times i.e. in the range [1, 50] 🤓💛.
Your like could help in recommending the article to others 👻