A string contains three kinds of brackets: (), [], and {}. Return true if they
are properly balanced and nested — every closer matches the most recent unmatched
opener of the same type.
befittingBrackets(s)
Input format: a single string of brackets.
"(){}[]" // → true
"([]{})" // → true
"[(])" // → false
The natural extension of single-bracket matching: three types now, and they nest. The rule isn't "equal counts of each type" — a closer must match the most recently opened, still-unclosed bracket of the same type. "Most recent, still open" is the giveaway for last-in-first-out.
With one type, every opener was interchangeable. With three, that breaks: [(]) has one of each bracket type — balanced by count — but the nesting is crossed, since ) appears before the ] that should close first. Counting can't detect crossing; you need to know which brackets are open, in what order.
A stack remembers the sequence of open brackets, most recent on top — exactly "most recent, still open."
Back to [(]): push [, push (, hit ] — but the top is (, not [, so the match fails immediately, correctly flagging the crossing. The stack enforces that closers resolve brackets in strictly reverse order of opening — exactly what "properly nested" means, caught the moment it breaks rather than through some more complicated global count.
def befitting_brackets(s):
match = {")": "(", "]": "[", "}": "{"}
stack = []
for ch in s:
if ch in "([{":
stack.append(ch)
elif ch in ")]}":
if not stack or stack[-1] != match[ch]:
return False
stack.pop()
return len(stack) == 0
Sign in to join the discussion.
No comments yet. Be the first to ask a question.
Press Run to execute your code, or Submit to test and complete this problem.