Matching brackets
Check with a stack that parentheses, square brackets and braces open and close properly: each closing one must match the last one opened.
Counting openings and closings is not enough (([)] has equal counts but is wrong). Each closing bracket must match
the last bracket opened and not yet closed; "last opened, first closed" is exactly how a stack behaves.
- Time:
O(n) - Space:
O(n) - Horowitz–Sahni, chapter 3
{a*[b+(c-d)]}; three nested kinds, all matching.
def balanced(s):pairs = {")": "(", "]": "[", "}": "{"}stack = []for i in range(len(s)):ch = s[i]if ch in "([{":stack.append(ch)elif ch in pairs:if not stack:return Falsetop = stack.pop()if top != pairs[ch]:return Falsepair = top + chif stack:return Falsereturn True
Start
0123456789101112
{a*[b+(c-d)]}
stack—
Local variables
s'{a*[b+(c-d)]}'
Orange = changed in this step
Call stack
- balanced()line 1
Step 1 of 70
Explanation
The idea
Counting openings and closings is not enough (([)] has equal counts but is wrong). Each closing bracket must match
the last bracket opened and not yet closed; "last opened, first closed" is exactly how a stack behaves.
The algorithm
- Push an opening bracket.
- A closing bracket: the stack must not be empty and its top must be the same kind; pop it.
- At the end the stack must be empty.
Uses
Compilers, text editors (finding the matching bracket) and checking HTML/XML.
What to watch in the trace
- The
ipointer on the string and thestackcard, which shows the open brackets.