LeetCode ยท #150

Evaluate Reverse Polish Notation Solution

Evaluate an arithmetic expression in Reverse Polish Notation (postfix). Valid operators are +, -, *, /.

01
Section One ยท Problem

Problem Statement

๐Ÿท๏ธ

Difficulty

Medium

๐Ÿ”—

LeetCode

Problem #150

๐Ÿ—๏ธ

Pattern

Stack โ€” expression evaluation

You are given an array of strings tokens representing an arithmetic expression in Reverse Polish Notation. Evaluate the expression and return the result as an integer. Division truncates toward zero. The input is always a valid RPN expression.

Example 1
Input: tokens = ["2", "1", "+", "3", "*"] Output: 9 // ((2 + 1) * 3) = 9
Example 2
Input: tokens = ["4", "13", "5", "/", "+"] Output: 6 // (4 + (13 / 5)) = 4 + 2 = 6
Constraints
โ€ข 1 โ‰ค tokens.length โ‰ค 10โด โ€ข tokens[i] is an operator (+, -, *, /) or an integer in [-200, 200] โ€ข Division truncates toward zero โ€ข Input always represents a valid RPN expression
02
Section Two ยท Approach 1

Why No Brute Force?

RPN was invented for stack-based evaluation. There's no simpler approach โ€” the stack solution is both the natural and optimal way to evaluate postfix expressions. Without a stack, you'd need to recursively reconstruct the expression tree, which is more complex, not simpler.

Context:
  • RPN (postfix notation) eliminates the need for parentheses and operator precedence rules.
  • The stack processes it in a single left-to-right pass.
  • This is exactly how calculators and many programming language VMs (like the JVM bytecode interpreter) evaluate expressions internally.
03
Section Three ยท Approach

Stack Evaluation โ€” O(n)

Scan tokens left to right. If it's a number, push onto stack. If it's an operator, pop two operands, apply the operator, and push the result back. The final answer is the one remaining element on the stack.

๐Ÿ’ก Mental model: Think of stacking ingredients for a recipe. Numbers are ingredients that pile up. An operator is a cooking step: take the top two ingredients, combine them, and put the result back. At the end, you have one finished dish โ€” the answer.
Algorithm
  • Step 1: Create an empty stack.
  • Step 2: For each token: if it's a number, push it.
  • Step 3: If it's an operator, pop b (top) then a (second). Compute a op b. Push result.
  • Step 4: Return the single element remaining on the stack.
โš  Operand order matters:
  • Pop b first, then a. The operation is a op b, not b op a.
  • For subtraction and division, order changes the result: "4 2 -" = 4 โˆ’ 2 = 2, not 2 โˆ’ 4 = โˆ’2.
04
Section Four ยท Trace

Visual Walkthrough

Trace through ["2", "1", "+", "3", "*"]:

Stack โ€” push numbers, pop-compute-push on operators
TOKENS: "2" "1" "+" "3" "*" "2": number โ†’ push stack: [2] "1": number โ†’ push stack: [2, 1] "+": pop 1, pop 2 โ†’ 2+1=3, push stack: [3] "3": number โ†’ push stack: [3, 3] "*": pop 3, pop 3 โ†’ 3*3=9, push stack: [9] One element left โ†’ answer is 9 Answer: 9 โœ“
05
Section Five ยท Implementation

Code โ€” Java & Python

Java โ€” Stack Evaluation
import java.util.Stack; class Solution { public int evalRPN(String[] tokens) { Stack<Integer> stack = new Stack<>(); for (String token : tokens) { switch (token) { case "+": stack.push(stack.pop() + stack.pop()); break; case "-": { int b=stack.pop(), a=stack.pop(); stack.push(a-b); break; } case "*": stack.push(stack.pop() * stack.pop()); break; case "/": { int b=stack.pop(), a=stack.pop(); stack.push(a/b); break; } default: stack.push(Integer.parseInt(token)); } } return stack.pop(); } }
Python โ€” Stack Evaluation
class Solution: def evalRPN(self, tokens: list[str]) -> int: stack = [] for token in tokens: if token in "+-*/": b, a = stack.pop(), stack.pop() if token == '+': stack.append(a + b) elif token == '-': stack.append(a - b) elif token == '*': stack.append(a * b) else: stack.append(int(a / b)) # truncate toward 0 else: stack.append(int(token)) return stack[0]
06
Section Six ยท Analysis

Complexity Analysis

ApproachTimeSpaceTrade-off
Stack โ† only approach O(n) O(n) Each token processed once. Stack holds at most (n+1)/2 numbers.
07
Section Seven ยท Edge Cases

Edge Cases & Pitfalls

CaseInputWhy It Matters
Single number["42"]No operators โ€” push 42, return 42.
Negative numbers["-1", "2", "+"]Negative tokens like "-1" must be parsed, not confused with "-" operator.
Division truncation["7", "-2", "/"]7 / -2 = -3.5 โ†’ truncate toward zero = -3 (not -4).
Subtraction order["4", "2", "-"]Pop b=2, a=4. Result = 4-2=2. Swapping gives wrong answer.
โš  Common Mistake (Python): Using // for integer division. In Python, -7 // 2 = -4 (floor division), but the problem wants truncation toward zero: -7 / 2 = -3. Use int(a / b) instead of a // b to truncate correctly for negative results.

โ† Back to Stack problems