2Brute2Best
🔥0

Evaluate Reverse Polish Notation

Medium·LeetCode #150Basic Anchor
LeetCode
30-Second Mental ModelStack — Expression evaluation (operand stack)
Complexity:O(N²)→O(N)
Key Insight

Read the tokens once from left to right. Every number is pushed on a stack, where it waits for its operator. An operator always uses the two most recent waiting numbers, which are the top two of the stack. Pop them, compute a op b, and push the result, because the result is now a waiting number too.

Core Validity Invariant

An operator always applies to the two most recent unused numbers, which are exactly the top two of the stack: b on top is the right side, a under it is the left side.

01

Problem

You are given an arithmetic expression written in Reverse Polish Notation (RPN), as a list of tokens. Return its value.

In RPN the operator comes after its two operands. So 3 4 + means 3 + 4, and 2 1 + 3 * means (2 + 1) * 3. There are no brackets, because the order of the tokens already says what gets computed first.

  • The operators are +, -, * and /.
  • Each operand is an integer, or the result of an earlier part of the expression.
  • Division between two integers truncates toward zero (7 / -2 = -3).
  • The expression is always valid and never divides by zero.
Input

A list of strings tokens. Each token is either one of "+", "-", "*", "/", or an integer like "42" or "-11".

Output

The integer value of the expression.

Example 1
Input: tokens = ["2", "1", "+", "3", "*"]
Output: 9

2 1 + gives 3, then 3 3 * gives 9. In normal notation: (2 + 1) * 3.

Example 2
Input: tokens = ["4", "13", "5", "/", "+"]
Output: 6

13 5 / gives 2 (13 / 5 = 2.6, cut to 2). Then 4 2 + gives 6. In normal notation: 4 + (13 / 5).

Example 3
Input: tokens = ["10", "6", "9", "3", "+", "-11", "*", "/", "*", "17", "+", "5", "+"]
Output: 22

In normal notation this is ((10 * (6 / ((9 + 3) * -11))) + 17) + 5. The inner part is 12 * -11 = -132, then 6 / -132 = 0, then 10 * 0 = 0, then 0 + 17 + 5 = 22.

Constraints
  • • 1 ≤ tokens.length ≤ 10^4
  • • Each token is an operator (`+ - * /`) or an integer in the range [−200, 200]
  • • The expression is valid, and every intermediate result fits in a 32-bit int
02

First, think yourself

Before opening any solution, try to answer these on paper. Use hints only when stuck — each hint is counted.

  1. 1.

    When I read an operator, which two numbers does it work on?

  2. 2.

    Do I ever need a number again after an operator has used it?

  3. 3.

    Once an operator produces a result, how should I treat that result for the operators that come later?

  4. 4.

    For - and /, the order of the two operands matters. Which one is the left side?

  5. 5.

    How can I tell the token "-" apart from the token "-11"?

03

Brute force approach

05

Optimized approach

06

Why does this algorithm work?

07

Dry run

08

All approaches compared

ApproachIdeaTimeSpace
Brute ForceFind the first "num num op", replace it by its value, rescan from the startO(N²)O(N)
OptimalPush numbers; on an operator pop b, pop a, push a op bO(N)O(N)
09

Why does this belong to this pattern?

Clues in the problem statement
  • “operator comes after its operands”When an operator appears, its operands were the most recent values → take them from the top of a stack.
  • “operand can be the result of an earlier part”A computed result must be usable later like a plain number → push it back.
  • “no brackets needed”The order is already fixed by the token order, so there is no precedence logic at all.
Operator after its operands+latest unused values+result becomes a new operand→Stack — Expression evaluation (operand stack)

This is the anchor of the sub-pattern: numbers wait on a stack until their operator arrives. In RPN the operator always arrives right after its operands, so every operator can be applied immediately. In Basic Calculator II the operator comes between its operands and * / / beat + / -, so we must decide when a number is allowed to be combined. In Basic Calculator, brackets add a new level, and the stack saves the outer level's state instead of plain numbers.

10

Don't make this mistake

Popping the operands in the wrong order
✗ long long a = st.top(); st.pop(); long long b = st.top(); st.pop(); st.push(a - b);
✓ long long b = st.top(); st.pop(); // right side long long a = st.top(); st.pop(); // left side st.push(a - b);

3 5 - means 3 − 5 = −2. The top of the stack is the number pushed last, which is the right-hand side. Getting this wrong only shows up for - and /, so it can pass the first example and still be wrong.

Treating "-11" as the minus operator
✗ if (t[0] == '-') { /* operator */ }
✓ bool isOp = t.size() == 1 && (t[0] == '+' || t[0] == '-' || t[0] == '*' || t[0] == '/');

A negative number also starts with -. Only a token of length exactly 1 can be an operator.

Rounding division the wrong way
✗ st.push(floor((double)a / b));
✓ st.push(a / b); // C++ integer division truncates toward zero

The problem wants truncation toward zero: 7 / -2 = -3. floor gives −4. C++ / on integers already does the right thing, so don't convert to double.

Using int for intermediate values
✗ stack<int> st;
✓ stack<long long> st;

LeetCode promises every result fits in an int, so int passes. But in a general evaluator one * of two large values overflows silently. long long costs nothing here and makes the code safe.

Thinking about precedence (pattern confusion)

RPN has no precedence rules and no brackets. 2 1 + 3 * is (2 + 1) * 3 because + comes first in the token list, not because of any rule. If you start writing code that compares * with +, you are solving Basic Calculator II instead. Here every operator is applied the moment it is read.

11

Want to implement this?

Write it yourself on LeetCode, then come back and compare your code with the solutions above.

Open coding workspace
How did it go?
Beyond The LeetCode Problem

How this concept connects to System Design & C++ Systems

Bridge DSA with production engineering

Top engineering interviews test whether you understand how algorithms like Stack translate into production architectures and low-level memory mechanics.