Browse curriculum

Basic Calculator II

Evaluate an expression with + - * / and no parentheses in one pass: a stack of terms where * and / are applied to the top right away.

Problem Understanding

Basic Calculator II: evaluate a valid expression string containing non-negative integers, +, -, *, / and spaces, with no parentheses. Integer division truncates toward zero. Built-in eval is not allowed.

Example: "3+2*2" returns 7, because 2*2 is done before the addition.

The Intuition: Multiply Now, Add Later

Precedence says * and / bind tighter than + and -. A stack of terms to add handles that in one pass:

  1. Read digits into num.
  2. When an operator (or the end) arrives, num is complete. Look at the operator before it, op:
    • +: push num; -: push -num. These wait.
    • * or /: pop the top, combine it with num, push the result. These happen now.
  3. Set op to the new operator and reset num.
  4. Sum the stack.

Starting with op = '+' makes the first number an ordinary push. Compare Evaluate Reverse Polish Notation, where the order of operations is already spelled out.

Interactive Walkthrough

The expression is on top, one character per cell; a space is drawn as ␣. Below it are the terms on the stack. Watch num grow digit by digit, then get pushed or folded into the top when the next operator arrives.

Dry Run Table

Input: "14-3/2"

Char num op before Action Stack after
1, 4 14 + — []
- 14 + push 14 [14]
3 3 - — [14]
/ 3 - push -3 [14, -3]
2 (end) 2 / -3 / 2 = -1 [14, -1]

Answer: 14 + (-1) = 13.

The Solution Template

A stack of terms, the number being read, and the operator in front of it. Java and C need / on ints, which already truncates toward zero; Python and JavaScript truncate explicitly.

Basic Calculator II Code
1var calculate = function(s) {
2 const stack = [];
3 let num = 0, op = '+';
4 for (let i = 0; i < s.length; i++) {
5 const c = s[i];
6 if (c >= '0' && c <= '9') num = num * 10 + Number(c);
7 if ((c !== ' ' && !(c >= '0' && c <= '9')) || i === s.length - 1) {
8 if (op === '+') stack.push(num);
9 else if (op === '-') stack.push(-num);
10 else if (op === '*') stack.push(stack.pop() * num);
11 else stack.push(Math.trunc(stack.pop() / num));
12 op = c;
13 num = 0;
14 }
15 }
16 return stack.reduce((a, b) => a + b, 0);
17};

Edge Cases & Common Mistakes

  • Multi-digit numbers: build num across characters; do not treat each digit as a number.
  • Spaces: skip them, but still finish the last number when the string ends in a space or a digit (i == n - 1).
  • Negative division: -3 / 2 must be -1. Python's // gives -2; use int(a / b).
  • Using the current operator: the action belongs to the operator before the number; keep op one step behind.
  • Overflow: intermediate products fit in 32 bits for LeetCode's inputs; C++ and C keep num as long while it is read.

Summary

Read numbers digit by digit. When a number ends, the operator before it decides: push it, push its negation, or fold it into the top with * or /. Only additions remain, so return the sum of the stack. O(n) time, O(n) space, or O(1) with a running total.

More practice: DSA interview questions with answers · patterns cheat sheet

The approach, step by step

  1. Build the current number

    For each digit, num = num * 10 + digit.

  2. Finish it at an operator or the end

    Using the previous operator: '+' pushes num, '-' pushes -num, '*' and '/' replace the top with top * num or top / num (truncated). Then set op to the current character and num to 0.

  3. Sum the stack

    Every term left on the stack is added; that sum is the answer.

Frequently asked questions

How does the stack handle operator precedence in Basic Calculator II?

Multiplication and division are applied immediately to the top of the stack, so they finish before any addition. Additions and subtractions are deferred by pushing +num or -num. At the end only additions remain, so the answer is the sum of the stack.


Why does the code look at the previous operator, not the current one?

When an operator arrives, the number before it has just ended, and what to do with that number depends on the operator in front of it. Keeping op as the last operator seen, starting at '+', gives exactly that.


Can it be done in O(1) space?

Yes. Only the last term can ever be changed by * or /, so keep a running total plus a single lastTerm instead of a stack. On + or -, add lastTerm to the total and start a new one.

Applying for software engineering roles? Free, no sign-up:

AI resume checker — match your resume to the job description