Evaluate an arithmetic expression with integers, operators +, -, *, /, and parentheses ( ). The expression is always valid. Integer division truncates toward zero.
This extends Basic Calculator II by adding nested parentheses. Two stacks handle this: one for operands, one for operators. When an operator arrives, while the top of the operator stack has equal or higher precedence, pop and compute. Parentheses mark expression boundaries: push ( to operator stack, and when ) is encountered, compute until matching (. This is the shunting-yard algorithm adapted for evaluation.
The two-stack approach (one for operands, one for operators) handles the full arithmetic expression evaluation. Numbers are pushed onto the operand stack. Operators are pushed onto the operator stack, but only after all operators with higher or equal precedence have been popped and evaluated. Parentheses create a sub-expression boundary: when an opening parenthesis is encountered, it is pushed as a marker. When a closing parenthesis is encountered, all operators until the matching opening parenthesis are evaluated.
This is the standard shunting-yard algorithm adapted for direct evaluation. Understanding this algorithm is essential for building expression evaluators and interpreters. The same technique applies to evaluating reverse Polish notation and Boolean expressions.
Integer division must truncate toward zero, which affects how negative results are computed. The expression is guaranteed to be valid and will not contain division by zero. Operators are evaluated with standard precedence rules: multiplication and division before addition and subtraction. Parentheses override precedence. This problem is commonly asked in senior-level interviews as it tests understanding of expression parsing, precedence, and stack-based evaluation.
Negative numbers are handled by the subtraction operator: when a minus sign is encountered, the next number is subtracted rather than added. Consecutive operators like 1--2 are not allowed in this problem. The input is always well-formed.
Example Input & Output
2*3=6, 1+6=7.
Parentheses first.
Nested parentheses.
Algorithm Flow

Solution Approach
Two stacks: nums and ops. Parse numbers. Handle operators with precedence. Parentheses create sub-expressions.
Time O(n), Space O(n).
Best Answers
import java.util.*;
class Solution {
public int solution(String s) {
Stack<Integer> nums = new Stack<>();
Stack<Character> ops = new Stack<>();
int i = 0;
while (i < s.length()) {
char ch = s.charAt(i);
if (ch >= '0' && ch <= '9') {
int num = 0;
while (i < s.length() && s.charAt(i) >= '0' && s.charAt(i) <= '9') { num = num * 10 + (s.charAt(i) - '0'); i++; }
nums.push(num); continue;
} else if (ch == '(') { ops.push(ch); }
else if (ch == ')') {
while (!ops.isEmpty() && ops.peek() != '(') calc(nums, ops);
ops.pop();
} else if ("+-*/".indexOf(ch) >= 0) {
while (!ops.isEmpty() && prec(ops.peek()) >= prec(ch)) calc(nums, ops);
ops.push(ch);
}
i++;
}
while (!ops.isEmpty()) calc(nums, ops);
return nums.pop();
}
void calc(Stack<Integer> nums, Stack<Character> ops) {
int b = nums.pop(), a = nums.pop();
char op = ops.pop();
if (op == '+') nums.push(a + b); else if (op == '-') nums.push(a - b);
else if (op == '*') nums.push(a * b); else nums.push(a / b);
}
int prec(char op) { return op == '*' || op == '/' ? 2 : op == '(' ? 0 : 1; }
}Comments (0)
Join the Discussion
Share your thoughts, ask questions, or help others with this Challenge.
