
Check for balanced parentheses using stack
Check for balanced parentheses using stack
See complete series on data structures here:
• Data structures
Algorithm or program to check for balanced parentheses in an expression using stack data structure. This is a popular programming interview question.
See source code here:
https://gist.github.com/mycodeschool/…
For practice problems and more, visit: http://www.mycodeschool.com
Like us on Facebook: https://www.facebook.com/MyCodeSchool
Follow us on twitter: https://twitter.com/mycodeschool
Content
0.429 -> In our previous lesson, we saw one simple
application of stack
3.75 -> we saw that stack can be used to
6.82 -> reverse a list or collection or may be to
simply traverse
10.79 -> a list or collection in reverse order. In
this lesson, we will discuss another
14.769 -> famous problem that can be solved using
stack.
18 -> And this is also a popular programming
interview question
21.85 -> and the problem is, given an expression
in the form of
25.82 -> a string comprising of let's say
constants,variables,
30.369 -> operators and parenthesis and when I
say parenthesis I also want to include
35.999 -> curly braces and brackets and my
definition of parenthesis.
39.519 -> so my expression or string can contain
characters that can be
44.01 -> upper or lower case letters, symbols for
operators
47.879 -> and an opening or closing parenthesis
51.519 -> or an opening or closing curly brace
on an opening or closing square
56.28 -> bracket. Let's write down some expressions
here. I'm going to write
60.17 -> a simple expression. We have one simple
expression with one pair of opening
64.809 -> and closing parenthesis.
66.29 -> Here in this expression we have nested
parenthesis.
69.79 -> Now given such expressions we want to
write a program
73.65 -> that would tell us whether parenthesis
in the expression
77.16 -> are balanced or not and what do we
really mean by balanced parenthesis
81.61 -> what we mean by balanced parenthesis
83.76 -> is that corresponding to each opening
parenthesis
87.3 -> or opening curly brace or opening
bracket we should have
90.46 -> a closing counter part in correct
93.48 -> order. These two expressions here are
balanced.
97.1 -> However this next expression is
100.23 -> not balanced.A closing curly brace is
missing here
104.57 -> This next expression is also not balanced
because we're missing
108.58 -> an opening square bracket here. This
next one is also not balanced because
113.49 -> corresponding to this opening curly
brace we do not have
116.35 -> a closing curly brace and corresponding
to this closing
119.36 -> parenthesis we do not have an
opening parenthesis. if we are opening
122.909 -> with a curly brace,we should also close
with a curly brace.These
126.11 -> 2 count for each other.Checking for
balanced parenthesis is one of the
131.079 -> tasks performed by a compiler, when we
write a program we often miss
136.48 -> an opening or closing curly brace
or an opening or closing parenthesis.
141.769 -> Compiler must check for this balancing
and if symbols are not balanced
147.18 -> it should give you an error.In this
problem here
150.65 -> what's inside parenthesis does not
matter,
153.93 -> we do not want to check for correctness
of anything that is inside
157.639 -> a parenthesis so in the string any character
other than opening and closing
162.209 -> parenthesis or opening and closing
curly brace or opening and closing
165.859 -> square bracket
166.79 -> can be ignored. This problem sometimes is
better stated like this
171.54 -> "Given a string comprising only of
opening and closing characters
175.9 -> of parenthesis braces or brackets
178.9 -> we want to check for balancing". So only
these characters and their order is
184.739 -> important.
185.469 -> While parsing a real expression we can
simply ignore other characters.
189.95 -> All we care about is these characters
and their order.
193.129 -> Okay so now how do we solve this problem?.
One straight forward thing that comes to
197.959 -> mind is
198.859 -> that because we should have a
closing counter part for
202.709 -> an opening parenthesis or opening curly
brace
205.989 -> or opening square bracket what we can
do is, we can count the number of
210.219 -> opening and closing symbols for each of
these
213.379 -> three types and they should be equal. So
the number of opening parenthesis should
217.999 -> be equal to number of closing parenthesis.
219.95 -> and the number of opening curly braces
should be equal to number of closings
224.2 -> curly braces and same should be true
for square brackets as well
227.859 -> but it will not be good enough this
expression here
231.709 -> has one opening parenthesis and one
closing parenthesis
235.459 -> but it's not balanced this next one
238.859 -> is balanced but this one with same number
of characters
242.9 -> of each type as the second expression is
not balanced
246.829 -> so this approach won't work. Apart from
count being equal that are some other
252.219 -> properties that must be conserved.
254.569 -> Every opening parenthesis must find a
closing counterpart to its right
259 -> and every closing parenthesis must find
an opening counterpart
263.77 -> in its left which is not true in the
first expression.
268.02 -> And the other property that must be
conserved is that a parenthesis
271.83 -> can close
272.66 -> only when all the parenthesis opened
275.68 -> after it are closed. This parenthesis has
been opened after
280.55 -> this square bracket so this square
bracket
284.04 -> can not close unless this parenthesis is
closed.
287.7 -> Anything that is opened last
291.04 -> should be closed first. Well actually it
should not
294.11 -> be last opened first closed in this
example here
297.63 -> this is getting opened last but this guy I
301.9 -> that is open previous to this is closed
first
305.01 -> and it is fine. The property that must be
conserved is that
308.57 -> as we scan the expression from left to
right
311.9 -> any closer should be for the previous
unclosed parenthesis
316.67 -> any closer should be for the last
unclosed.
320.7 -> Let's scan some expressions from left to
right and see how it's true.
325.42 -> Let's scan this last one we will go from
left to right
329.16 -> first character an opening of the
square bracket
332.34 -> second one is an opening parenthesis
335.57 -> Lets mark opening of closed parenthesis
in red.
340.2 -> Okay now we have a closer here ,
the third character is a closer.
344.44 -> this should be the closer for last
unclosed.
348.48 -> So this should be the closer for this
one, this guy,
352.85 -> this opening parenthesis. last unclosed
now is this guy.
358.54 -> Next character once again is an opening
parenthesis.
362.21 -> Now we have two unclosed parenthesis at
this stage and this one is the last
366.76 -> unclosed,
368.25 -> the next one's a closure.So it
should be closer for the last unclosed.
373.7 -> Now the last unclosed once again is the
opening of square bracket
377.89 -> now when we have a closer it should be
closer
381.15 -> for this guy.
384.509 -> we can use this approach to solve this
problem what we can do is we can
387.96 -> scan the expression from left to right
390.449 -> and as we scan at any stage we can
keep track of
394.169 -> all the unclosed parenthesis basically
what we can do is whenever we
398.35 -> get an opening symbol an opening
parenthesis an opening curly brace or
403.09 -> an opening square bracket, we can add it
406.539 -> to a list. If we get up closing symbol
410.46 -> it should be the closer for the last
element in the list,
413.8 -> in case of an inconsistency like if
417.1 -> the last opening symbol in the list is
not of the same type as the
420.87 -> closing symbol or if there is no last
opening symbol at all because the list
425.51 -> is
425.949 -> empty. We can stop this whole process and
say that
429.31 -> parenthesis are not balanced else we can
removed the last opening symbol in the
433.83 -> list
434.36 -> because we have got its counterpart and
continue this whole process.
438.82 -> Things will be further clear if I will
run through an example.
442.22 -> I will run through this last example
once again.
445.43 -> We are going to scan this expression
from left to right
448.91 -> and we will maintain a list to keep
track of all the
452.15 -> opening parenthesis that are not yet
closed.
455.47 -> We will keep the track of all the unclosed
parenthesis
458.76 -> opened but not closed. Initially this
list is empty,
462.07 -> the first character that we have got is
an opening of square bracket.
466.94 -> This will go into the list and we will
move to the next character
470.44 -> the next character is an opening parenthesis
so one stick,
473.849 -> once again it should go to the list.
We should always insert at the end in the
479.07 -> list.
479.539 -> the next character is a closing of
parenthesis now we must look at the
484.099 -> last
484.68 -> opening symbol in the list and if it is
of the same type
488.9 -> then we have got it's counterpart and we
should remove this.
492.08 -> Now we move on to the next character
this is once again an opening
495.69 -> parenthesis,
496.53 -> it should go in the list at the end.
499.55 -> The next character is a closing of
parenthesis so we will look at
503.49 -> the last element in the list, it's an
opening parenthesis,
507.96 -> so we can remove it from the list and
now we go to the last character which is
512.94 -> a closing of square bracket once again
we need to look at
515.69 -> the last element in the list we have one
519.27 -> element only one element in the list at
this stage, its
522.64 -> an opening of square bracket so once
again we can remove it from the list.
526.839 -> Now we're done scanning the list and
the list is empty once again
531 -> if everything is alright if parenthesis
are balanced
534.13 -> we will always end with an empty list
537.32 -> and if list is not empty then some
opening parenthesis haven't found its
542.38 -> closing counterpart
543.75 -> and expression is not balanced. One thing
worth noticing here is that
548.18 -> we are always inserting and removing
551.23 -> one element at a time from the same end
of the list
554.51 -> in this whole process whatever is coming
in last in the list is going out first,
559.589 -> there is a special kind of list that
562.64 -> enforces this behavior that element should
be inserted and removed
567.01 -> from the same end and we call it a
stack.
570.72 -> In a stack we can insert and remove an
element one at a time from the same
575.709 -> end in constant time. so what we can do
is whenever we get
579.63 -> an opening symbol while scanning the
list we can push it onto the stack
584.57 -> and when we get a closing symbol we can
check whether
588 -> the opening symbol at the top of stack
is of the same type
592.209 -> has the closing symbol, if its of the
same type we can pop,
595.79 -> if it's not of the same type we can
simply say that parenthesis are not
600.339 -> balanced
601.02 -> I will quickly write pseudocode for this
logic
604.07 -> I'm going to write a function named
CheckBalancedParenthesis() that will
607.86 -> take an expression
609.11 -> in the form of a string as argument.
612.68 -> first of all iI will store the number
of characters
615.73 -> in the string in a variable and then
619.02 -> I will create a stack and I will create
a stack of characters
623.68 -> and now I will scan the expression
from left to right using
627.66 -> a loop, while scanning if the character is
an opening symbol if
631.88 -> it's an opening parenthesis or opening
curly brace or opening square bracket
636.579 -> we can push that character onto the
stack, let's say this function
639.85 -> Push() will push up character onto
642.94 -> S else if exp[i] or the
character
646.74 -> at ith position while scanning is a
closing symbol of
650.48 -> any of the three types. We can have two
scenarios if stack is empty,
655.55 -> or top of stack does not pair with the
closing symbol
660.8 -> if we have a closing of Parenthesis then
the top of stack should be an opening of
665.569 -> Parenthesis.
666.709 -> It cannot be an opening of curly brace,
in such a scenario we can conclude that
671.14 -> the parenthesis
672.47 -> are not balanced else we can perform
675.6 -> a pop. Finally once a scanning is over
678.949 -> we can check whether a stack is empty or
not if it's empty Parenthesis are balanced
683.39 -> if it's not they are not balanced.
686.41 -> so this is my pseudo code let's run
through a couple of examples and see
690.76 -> whether this works for all scenarios
all test cases or not.
694.68 -> Let's first look at this expression, the
first thing that we're doing in our
698.52 -> code is that we're creating a stack
of characters,
701.67 -> I have drawn logical representation of a
stack here.
705.49 -> Okay now let's scan this string, let's say
we have a zero-based index
709.63 -> and a string is just are character array, we
are starting the scan and going inside
714.4 -> the loop.
715.329 -> This is a closing of Parenthesis
so this if statement will not hold true
718.93 -> so we will go to the
720.24 -> else condition and now we will go inside
the else
724.04 -> to check for this condition whether stack
is empty or not
727.069 -> or whether the top of stack pairs
730.68 -> with this closing symbol or not, the stack
is empty,
734.199 -> if the stack is empty there is no opening
counterpart for this closing symbol.
739.079 -> so we will simply return false, returning
means exiting the function
743.62 -> so we are simply concluding here that Parenthesis
are not balanced and
747.29 -> exiting.
749.179 -> Let's go through this one now, first we
have
751.92 -> an opening squad bracket so here we go
to the first
755.439 -> if and push, next one is an
758.829 -> opening parenthesis once again it will
be pushed next one
762.569 -> is a closing square bracket, so the
condition for this else if will be true we
767.339 -> will go inside this
768.54 -> else if, now this time to top of stack
771.86 -> is an opening parenthesis it should have
774.98 -> been an opening square bracket and then
only we would have
778.98 -> a pair so this time also we will have
to return false
782.879 -> and exit. Okay now let's go through this
one.
787.149 -> First we'll have a push, the next one
790.579 -> will also be a push, now next one is a
closer of parenthesis
795.179 -> which pairs with the top of stack which
is opening of parenthesis
799.379 -> so we will have a pop, we will go to the
next character and this one once again
804.829 -> is an opening parenthesis so there will
be a push.
807.41 -> next one is a closing parenthesis and
the top is an opening parenthesis ,they
811.999 -> pair so there will be a pop, last
character is a
815.579 -> closing curly brace so once again
we will see whether the top of stack
820.369 -> is an opening curly brace or not? do we
have a pair or not?
823.67 -> yes we have a pair so there will be a
pop with this
827.679 -> our scanning will finish and finally
stack should be empty
831.579 -> it is empty so we have balanced Parenthesis
here
835.279 -> try implementing this pseudo code in the
language of your choice and see whether
839.649 -> it works for all test cases or not.
841.589 -> If you want to look at my implementation
you can check the description of this
844.999 -> video
845.6 -> for a link. In the coming lessons we will
see some more problems on stack.
849.86 -> This is it for this lesson, thanks for
watching!!
Source: https://www.youtube.com/watch?v=QZOLb0xHB_Q