Talentd
FleetCode
Make and follow sheets.Sign in

Basic Calculator III solution and explanation

HardMathRecursionStackString5 min read53.2% acceptanceUpdated 23 Mar 2026Premium elsewhere, free here
LeetCode 224,227,772 Basic Calculator 1,2,3 Explanation and Solutionhappygirlzt · 19:25 · 13K viewsWatch on YouTube
9 more videos on this problem
  1. LeetCode 224,227,772 Basic Calculator 1,2,3 Explanation and Solutionhappygirlzt · 19:25 · 13K views
  2. BASIC CALCULATOR III | LEETCODE # 772 | PYTHON SOLUTIONCracking FAANG · 13:05 · 11K views
  3. Basic Calculator III | Leetcode 772Pepcoding · 28:43 · 6K views
  4. [Java] Leetcode 772. Basic Calculator III [Stack & Queue #9]Eric Programming · 7:14 · 3K views
  5. 【每日一题】772. Basic Calculator III, 5/27/2020Huifeng Guan · 23:11 · 2K views
  6. 772. Basic Calculator III , Top Interview DSA Questions, Java Solution with time complexityShrayansh Jain · 15:49 · 2K views
  7. Baozi Training Leetcode 772 solution: Basic Calculator IIIBaozi Training · 12:55 · 1K views
  8. leetcode log(小雨)772. Basic Calculator IIILing Chen · 25:02 · 459 views
  9. Universal Solution for Basic Calculator I, II, and IIINeedCode⚡ · 13:48 · 383 views
  10. Leetcode 772 Basic Calculator III带老婆转码 · 13:58 · 253 views

The problem

Implement a basic calculator to evaluate a simple expression string.

The expression string contains only non-negative integers, '+', '-', '*', '/' operators, and open '(' and closing parentheses ')'. The integer division should truncate toward zero.

You may assume that the given expression is always valid. All intermediate results will be in the range of [-231, 231 - 1].

Note: You are not allowed to use any built-in function which evaluates strings as mathematical expressions, such as eval().

Example 1:

Input: s = "1+1"
Output: 2

Example 2:

Input: s = "6-4/2"
Output: 4

Example 3:

Input: s = "2*(5+5*2)/3+(6/2+8)"
Output: 21

Constraints:

  • 1 <= s <= 104
  • s consists of digits, '+', '-', '*', '/', '(', and ')'.
  • s is a valid expression.

Approach overview

Problem Overview: You need to evaluate a string arithmetic expression containing integers, operators +, -, *, /, and nested parentheses. The expression may include spaces, and operator precedence must be respected while correctly handling parentheses.

Approach 1: Recursive Expression Evaluation (O(n) time, O(n) space)

This approach processes the string using recursion to evaluate sub-expressions inside parentheses. Iterate through the characters, build numbers digit by digit, and apply operators when encountered. When you see (, recursively evaluate until the matching ). A stack tracks intermediate values so multiplication and division can be applied immediately while addition and subtraction defer until summation. Each character is processed once, giving O(n) time and recursion/stack usage of O(n) space.

Approach 2: Two-Stack Expression Parsing (O(n) time, O(n) space)

This classic expression evaluator uses one stack for numbers and another for operators. Iterate through the string, push numbers to the value stack, and push operators while respecting precedence rules. Before pushing a new operator, resolve any operators with higher or equal precedence already on the stack. Parentheses trigger evaluation until the matching opening bracket. This mirrors the Shunting Yard technique and handles precedence cleanly using explicit operator comparisons.

Approach 3: Single Stack with Precedence Handling (O(n) time, O(n) space)

The optimized solution scans the string once and uses a single stack to manage numbers. Track the previous operator and apply logic when a new operator or closing parenthesis appears. Push numbers for + and -, but immediately compute * or / with the stack top. When encountering (, recursively evaluate the inner expression and treat the returned value as the current number. This approach combines operator precedence and parenthesis handling efficiently while keeping the code concise.

These solutions rely heavily on concepts from stack-based parsing and recursive expression evaluation from recursion. Since the problem operates on characters and tokens inside an expression string, familiarity with string traversal is essential.

Recommended for interviews: The single-stack recursive evaluation is what interviewers typically expect. It shows you understand operator precedence, expression parsing, and stack-based evaluation in linear time. Mentioning the two-stack parsing method first demonstrates foundational understanding, but implementing the optimized single-pass approach proves stronger problem-solving ability.

Solution

class Solution:
    def calculate(self, s: str) -> int:
        def dfs(q):
            num, sign, stk = 0, "+", []
            while q:
                c = q.popleft()
                if c.isdigit():
                    num = num * 10 + int(c)
                if c == "(":
                    num = dfs(q)
                if c in "+-*/)" or not q:
                    match sign:
                        case "+":
                            stk.append(num)
                        case "-":
                            stk.append(-num)
                        case "*":
                            stk.append(stk.pop() * num)
                        case "/":
                            stk.append(int(stk.pop() / num))
                    num, sign = 0, c
                if c == ")":
                    break
            return sum(stk)

        return dfs(deque(s))
class Solution {
public:
    // Define an operation function that performs mathematical operations based on the operator
    int operate(int b, char ch, int a) {
        // Note the order of ab
        switch (ch) {
        case '+':
            return a + b; // Addition
        case '-':
            return a - b; // Subtraction
        case '*':
            return a * b; // Multiplication
        case '/':
            return a / b; // Division
        default:
            break;
        }
        return 0; // Default return 0, handle invalid operators
    }

    // Calculate the value of the string expression
    int calculate(string s) {
        int preority[250]; // Operator precedence array
        preority['+'] = 1;
        preority['-'] = 1;
        preority['*'] = 2;
        preority['/'] = 2;
        preority['('] = 0;
        preority[')'] = 0;

        stack<char> op; // Operator stack
        stack<int> num; // Operand stack
        int stringsize = s.size(); // Length of the string
        int i = 0;
        char ch;

        // Traverse the string
        for (; i < stringsize; i++) {
            ch = s[i];
            if (ch == ' ') {
                continue; // Skip spaces
            }
            if (ch >= '0' && ch <= '9') {
                int realnum = ch - '0'; // Convert character to number
                // Handle multi-digit numbers
                while (s[i + 1] >= '0' && s[i + 1] <= '9') {
                    i++;
                    realnum *= 10;
                    realnum += s[i] - '0';
                }
                num.push(realnum); // Push the number onto the stack
            } else {
                // Handle operators
                if (op.empty() || ch == '(' || preority[ch] > preority[op.top()]) {
                    // Special case, handle the first character being '-' or '+'
                    if (num.empty() && (ch == '-' || ch == '+')) {
                        num.push(0);
                    }
                    op.push(ch); // Push the operator onto the stack
                    // Handle expressions inside parentheses
                    if (ch == '(') {
                        int j = i;
                        while (j + 1 < stringsize) {
                            // Preprocess the first operator inside the parentheses
                            if (s[j + 1] == '-' || s[j + 1] == '+') {
                                num.push(0);
                            }
                            if (s[j + 1] != ' ') {
                                break;
                            }
                            j++;
                        }
                    }
                } else if (ch == ')') {
                    // Handle right parentheses
                    char ch2 = ')';
                    ch2 = op.top();
                    op.pop();
                    while (ch2 != '(') {
                        int a = num.top();
                        num.pop();
                        int b = num.top();
                        num.pop();
                        num.push(operate(a, ch2, b)); // Calculate and push the result
                        ch2 = op.top();
                        op.pop();
                    }
                } else if (preority[ch] <= preority[op.top()]) {
                    // Handle cases where the precedence is less than or equal to the top of the stack
                    char ch2;
                    ch2 = op.top();
                    while (!op.empty() && preority[ch] <= preority[op.top()] && ch2 != '(') {
                        op.pop();
                        int a = num.top();
                        num.pop();
                        int b = num.top();
                        num.pop();
                        num.push(operate(a, ch2, b)); // Calculate and push the result
                        if (!op.empty()) {
                            ch2 = op.top();
                        } else {
                            break;
                        }
                    }
                    op.push(ch); // Push the current operator onto the stack
                }
            }
        }

        // Handle the remaining expressions in the stack
        while (!op.empty()) {
            ch = op.top();
            op.pop();
            int a = num.top();
            num.pop();
            int b = num.top();
            num.pop();
            num.push(operate(a, ch, b)); // Calculate and push the result
        }

        return num.top(); // Return the final result
    }
};
Try this approach in the editor

Complexity analysis

ApproachTimeSpaceWhen to Use
Recursive Expression EvaluationO(n)O(n)Clean handling of nested parentheses using recursion
Two-Stack Expression ParsingO(n)O(n)When implementing classic infix expression evaluation with precedence rules
Single Stack with Precedence HandlingO(n)O(n)Best interview solution; single pass with immediate handling of * and /

Frequently asked questions

Is Basic Calculator III easy or hard?

Basic Calculator III is rated Hard because it combines multiple concepts: string parsing, operator precedence, stack-based evaluation, and nested parentheses. While each idea is manageable individually, implementing them together correctly requires careful control flow and edge case handling.

Basic Calculator III Python/Java solution

In Python or Java, the common solution iterates through the string, builds numbers, and uses a stack to apply operators based on precedence. When encountering parentheses, a recursive helper evaluates the sub-expression and returns its result. The algorithm remains O(n) time and O(n) space across languages.

How to solve Basic Calculator III in O(n)?

Scan the expression from left to right while building numbers and tracking the previous operator. Use a stack to store intermediate values: push numbers for + and -, and immediately compute multiplication or division with the stack top. When encountering parentheses, recursively evaluate the inner expression and treat the result as a number. Every character is processed once, giving O(n) time.

What is the best approach for Basic Calculator III?

The best approach uses a stack combined with recursion to evaluate expressions while scanning the string once. Numbers are pushed to a stack and multiplication or division is computed immediately, while addition and subtraction are accumulated later. Parentheses trigger recursive evaluation of sub-expressions. This solution runs in O(n) time with O(n) space.

Is Basic Calculator III asked at Google/Amazon/Meta?

Expression evaluation and calculator-style parsing problems appear frequently in interviews at companies like Google, Amazon, and Meta. Variants such as Basic Calculator I, II, and III test understanding of stacks, recursion, and operator precedence handling.

What data structure is used in Basic Calculator III?

The primary data structure is a stack. It stores intermediate numbers while operators determine how values are combined. Recursion is often used alongside the stack to evaluate expressions inside parentheses.

What is the time complexity of Basic Calculator III?

The optimal solution runs in O(n) time where n is the length of the expression string. Each character is processed once while building numbers or applying operators. Stack operations are constant time, so the overall complexity remains linear with O(n) auxiliary space.

Comments

Now write it yourselfClose this page and solve Basic Calculator III in the editor, without looking.
Practise Basic Calculator III