Skip to content

Interview Solver

FeaturesPricingHelp
Sign In
FeaturesPricingHelpSign In
  1. Interview Questions
  2. /
  3. Problems
  4. /
  5. Basic Calculator

Basic Calculator

Evaluate a string expression with +, -, parentheses and unary minus, without eval. A single pass with a stack that saves your place at each open parenthesis. Solve it below in Python or JavaScript, then read the walkthrough.

HardMathStringStackRecursionAsked at 118 companies incl. Google, Amazon, Meta

Problem

You're given a string s holding a valid arithmetic expression. Evaluate it and return the integer result. You may not use any built-in function that evaluates strings as code (such as eval).

The expression contains only:

  • non-negative integers (possibly several digits long),
  • the binary operators + and -,
  • parentheses ( and ),
  • spaces, which can appear anywhere and should be ignored.

A - may also be unary, negating what follows it, but only at the very start of the expression or right after an (. A + is never unary, and two operators never appear next to each other.

Example 1

Input
s = "7 - (3 + 2)"
Output
2

Example 2

Input
s = "-(4 - 10) + 1"
Output
7

The leading minus negates the group: -(-6) + 1 = 7.

Example 3

Input
s = "12+ (5-(8 -2))"
Output
11

The inner group is 6, so the outer one is 5 - 6 = -1, and 12 + (-1) = 11.

Constraints

  • 1 ≤ s.length ≤ 3 × 10⁵
  • s contains digits, "+", "-", "(", ")" and spaces.
  • s is a valid expression.
  • Every intermediate value and the result fit in a signed 32-bit integer.

Practice

1
2
3
4

Runs 14 tests in your browser. Python loads on the first run (about 6 MB, then cached). Press ⌘/Ctrl + Enter to run.

Get asked Basic Calculator in a real interview?

Interview Solver gives you a working solution live, during your actual coding interview. Invisible to screensharing.

Start Free Trial

How to solve Basic Calculator

Pattern: Running sum with a stack of saved contexts

With only + and -, there's no precedence to worry about. Without parentheses you could just keep a running result and a sign (+1 or -1) for the next number: every time a number ends, add sign * number to result.

Parentheses are the only complication, and they nest like a stack. When you hit (, the work you've done so far is on hold: push the current result and the sign in front of the parenthesis, then start a fresh result of 0 for the inside. When you hit ), the inside is finished; pop the saved pair and fold it back in as saved_result + saved_sign * inside.

Unary minus falls out for free. At the start of the expression or right after (, result is 0, so a - just adds 0 and sets sign = -1 for what follows.

Approach 1: Recursive descent

Write a parser where parse_expression reads terms separated by +/-, and a term is either a number or ( expression ). Clear and easy to extend to * and /, but recursion depth equals the nesting depth, which can overflow the call stack on deeply nested input.

Time O(n) · Space O(n)

Approach 2: Convert to postfix, then evaluate

Run the shunting-yard algorithm to produce reverse Polish notation, then evaluate it with a value stack. Unary minus needs a special token (for example rewrite it as 0 -). Works, but it is two passes and more code than the problem needs.

Time O(n) · Space O(n)

Approach 3: Single pass with a sign stack

Track result, number (digits being read) and sign. For each character:

  1. Digit: number = number * 10 + digit.
  2. + or -: add sign * number to result, reset number, set sign to +1 or -1.
  3. (: push (result, sign), then reset result = 0, sign = 1.
  4. ): add sign * number to result, reset number, pop (saved, saved_sign) and set result = saved + saved_sign * result.
  5. Spaces: skip.

At the end return result + sign * number to include the last number.

Time O(n) · Space O(n)

ApproachTimeSpace
Recursive descentO(n)O(n)
Convert to postfix, then evaluateO(n)O(n)
Single pass with a sign stackO(n)O(n)

Solution code

Try the practice editor first. Both solutions pass every test above.

▸Basic Calculator solution in Python
def calculate(s: str) -> int:
    result = 0
    number = 0
    sign = 1
    stack = []  # (result before "(", sign in front of "(")
    for ch in s:
        if ch.isdigit():
            number = number * 10 + int(ch)
        elif ch == "+" or ch == "-":
            result += sign * number
            number = 0
            sign = 1 if ch == "+" else -1
        elif ch == "(":
            stack.append((result, sign))
            result, sign = 0, 1
        elif ch == ")":
            result += sign * number
            number = 0
            saved, saved_sign = stack.pop()
            result = saved + saved_sign * result
    return result + sign * number
▸Basic Calculator solution in JavaScript
function calculate(s) {
  let result = 0;
  let number = 0;
  let sign = 1;
  const stack = []; // [result before "(", sign in front of "("]
  for (const ch of s) {
    if (ch >= '0' && ch <= '9') {
      number = number * 10 + (ch.charCodeAt(0) - 48);
    } else if (ch === '+' || ch === '-') {
      result += sign * number;
      number = 0;
      sign = ch === '+' ? 1 : -1;
    } else if (ch === '(') {
      stack.push([result, sign]);
      result = 0;
      sign = 1;
    } else if (ch === ')') {
      result += sign * number;
      number = 0;
      const [saved, savedSign] = stack.pop();
      result = saved + savedSign * result;
    }
  }
  return result + sign * number;
}

Common mistakes

  • Reading only one digit per number. "42" must parse as forty-two, so accumulate digits until a non-digit appears.
  • Forgetting to add the final number after the loop. "7 - 3" ends on a digit, so nothing inside the loop flushes it.
  • Not flushing the pending number at `)` before popping, which drops the last number inside the group.
  • Applying the sign in front of `(` to only the first number inside, instead of to the whole group's value.
  • Using recursion on input with hundreds of nested parentheses and hitting the recursion limit in Python.

What interviewers look for

Clarify the grammar first: which operators, whether unary minus exists and where, and whether spaces can appear inside numbers (they can't here). Interviewers like hearing you pin that down.

Then explain the state you carry: "result so far, the number I'm reading, and the sign for it. A parenthesis pushes that state and starts fresh." Trace an example with a negated group, like -(4 - 10), since that's the case most solutions get wrong.

Follow-up questions

How would you add * and /?

Without parentheses, keep a stack of terms: push +n or -n for additive operators, and for * or / pop the top term, combine it with the new number, and push the result. Sum the stack at the end. With parentheses too, a recursive descent parser with separate expression and term levels is the cleanest.

Can you do it with O(1) extra space?

Not in general, since you need to remember the sign context for every open parenthesis. You can shrink the stack to only signs (push the effective sign for each group and multiply it into every number), but it still grows with nesting depth.

How would you report invalid input?

Track the previous token type to reject two operators in a row or an operator before `)`, check the stack is non-empty on `)`, and check it is empty at the end. Report the position of the first bad character.

Companies that ask Basic Calculator

Basic Calculator is tagged by 118 companies in our interview dataset. The score shows how often it comes up at each company.

  • Ch Robinson100%
  • Workspan100%
  • Intuitive100%
  • Adesso100%
  • Dandy100%
  • Rokt100%
  • Udemy98%
  • Motional96%
  • Cytokinetics94%
  • Lime94%
  • Traveloka92%
  • Supermicro89%
  • Mts89%
  • Doximity87%
  • Squarepoint Capital85.1%
  • Raytheon84%
  • Front84%
  • Genpact84%
  • Albertsons83%
  • Skillz83%
  • Procore Technologies82%
  • Disco Corporation81%
  • Relativity78%
  • Ripple77.9%

and 94 more.

Practice next

  • Decode StringMediumStack for nested structure
  • Basic Calculator IIMediumRunning term with deferred addition
  • Valid ParenthesesEasyStack of open brackets
  • Roman to IntegerEasyCompare each symbol with the next

Get live help in the real interview

Working solutions in real time during your actual interview. Invisible to screensharing.

Start Free Trial

No credit card required

Interview Solver
  • Home
  • About
  • Pricing
  • Sign in
  • Contact
  • Blog
  • Companion
  • Mobile
  • Help Center
  • Developers
  • Use Cases
  • Software Engineer
  • Product Manager
  • Misc
  • Privacy Policy
  • Terms and Conditions
  • Refund & Cancellation
  • Discord Community
  • Affiliate Program
  • Compare
  • All Comparisons
  • vs Final Round AI
  • vs UltraCode
  • vs Interview Coder
  • vs LockedIn AI
  • vs AI Apply
  • Free Tools
  • ATS Resume Checker
  • STAR Method Builder
  • Salary Lookup
  • Big O Cheat Sheet
  • Total Comp Calculator
  • View All →
  • Interview Questions
  • Google Questions
  • Amazon Questions
  • Microsoft Questions
  • Meta Questions
  • Apple Questions
  • TikTok Questions
  • View All →
© 2026 Interview Solver, Inc. All rights reserved.