Determine whether brackets in a string are balanced and correctly nested (e.g. "{[()]}" is valid, "([)]" is not).
Use a stack: push every opening bracket; on a closing bracket, the stack top must be its matching opener, otherwise it is unbalanced. The string is valid only if every closer matched and the stack is empty at the end. O(n) time, O(n) space.
public static boolean isBalanced(String s) {
Deque<Character> stack = new ArrayDeque<>();
Map<Character,Character> pairs = Map.of(')', '(', ']', '[', '}', '{');
for (char c : s.toCharArray()) {
if (c == '(' || c == '[' || c == '{') stack.push(c);
else if (pairs.containsKey(c)) {
if (stack.isEmpty() || stack.pop() != pairs.get(c)) return false;
}
}
return stack.isEmpty();
}function isBalanced(s) {
const stack = [];
const pairs = { ')': '(', ']': '[', '}': '{' };
for (const c of s) {
if (c === '(' || c === '[' || c === '{') stack.push(c);
else if (pairs[c]) {
if (stack.pop() !== pairs[c]) return false;
}
}
return stack.length === 0;
}def is_balanced(s):
stack = []
pairs = {')': '(', ']': '[', '}': '{'}
for c in s:
if c in '([{':
stack.append(c)
elif c in pairs:
if not stack or stack.pop() != pairs[c]:
return False
return not stackBracket matching is the heart of parsers, compilers, and expression evaluators — and a canonical stack question.
A candidate only counts openers vs closers and calls "([)]" balanced. Why is that wrong?