Skip to content

150. Evaluate Reverse Polish Notation (Medium)

Problem

Evaluate an arithmetic expression in Reverse Polish Notation. Valid operators are +, -, *, /. Each operand can be an integer or another expression. Division between two integers truncates toward zero.

Example

  • tokens = ["2","1","+","3","*"]9 (≡ (2 + 1) * 3)
  • tokens = ["10","6","9","3","+","-11","*","/","*","17","+","5","+"]22

LeetCode 150 · Link · Medium

Try it yourself

idle

Starter code: this editor begins with intentional TODOs. Fill the function, run the embedded tests, then compare your solution with the worked approaches below.

Click Run Python to execute. First run downloads Python (~10 MB, cached after that).

Approach 1: Stack with explicit if/elif branching

Standard RPN evaluation: push operands; on operator, pop two and apply.

def eval_rpn(tokens: list[str]) -> int:
stack = [] # L1: O(1)
for tok in tokens: # L2: n iterations
if tok in ("+", "-", "*", "/"): # L3: O(1) check
b = stack.pop() # L4: O(1) pop
a = stack.pop() # L5: O(1) pop
if tok == "+": # L6: O(1)
stack.append(a + b) # L7: O(1)
elif tok == "-":
stack.append(a - b) # L8: O(1)
elif tok == "*":
stack.append(a * b) # L9: O(1)
else:
stack.append(int(a / b)) # L10: O(1) truncate toward zero
else:
stack.append(int(tok)) # L11: O(1) parse + push
return stack[0] # L12: O(1)

Where the time goes, line by line

Variables: n = len(tokens).

LinePer-call costTimes executedContribution
L2 (loop)O(1)O(1)nO(n)O(n)
L3-L11 (per-token: push or pop+apply)O(1)O(1)nO(n)O(n) ← dominates
L12 (return)O(1)O(1)1O(1)O(1)

Each token is processed in O(1)O(1); one pass over all n tokens.

Complexity

  • Time: O(n)O(n), driven by L3-L11 (one push or pop+apply per token).
  • Space: O(n)O(n). Stack depth at most O(n)O(n).

Approach 2: Stack with operator dictionary (cleaner)

Replace the if/elif branching with a dict of lambdas.

def eval_rpn(tokens: list[str]) -> int:
ops = { # L1: O(1) constant dict
"+": lambda a, b: a + b,
"-": lambda a, b: a - b,
"*": lambda a, b: a * b,
"/": lambda a, b: int(a / b), # truncate toward zero
}
stack = [] # L2: O(1)
for tok in tokens: # L3: n iterations
if tok in ops: # L4: O(1) dict lookup
b = stack.pop() # L5: O(1)
a = stack.pop() # L6: O(1)
stack.append(ops[tok](a, b)) # L7: O(1) apply lambda
else:
stack.append(int(tok)) # L8: O(1) parse + push
return stack[0] # L9: O(1)

Where the time goes, line by line

Variables: n = len(tokens).

LinePer-call costTimes executedContribution
L1 (init ops dict)O(1)O(1)1O(1)O(1)
L3 (loop)O(1)O(1)nO(n)O(n)
L4-L8 (per-token: push or apply)O(1)O(1)nO(n)O(n) ← dominates
L9 (return)O(1)O(1)1O(1)O(1)

Functionally identical to Approach 1; easier to extend (new operators) and easier to read.

Complexity

  • Time: O(n)O(n), driven by L4-L8 (one push or pop+apply per token).
  • Space: O(n)O(n).

Try this approach:

idle
Click Run Python to execute. First run downloads Python (~10 MB, cached after that).

Summary

ApproachTimeSpaceNotes
Stack + if/elifO(n)O(n)O(n)O(n)Verbose
Stack + operator dictO(n)O(n)O(n)O(n)Cleanest

Test cases

# Quick smoke tests, paste into a REPL or save as test_eval_rpn.py and run.
# Uses the canonical implementation (Approach 2: stack + operator dict).
def eval_rpn(tokens: list[str]) -> int:
ops = {
"+": lambda a, b: a + b,
"-": lambda a, b: a - b,
"*": lambda a, b: a * b,
"/": lambda a, b: int(a / b),
}
stack = []
for tok in tokens:
if tok in ops:
b = stack.pop()
a = stack.pop()
stack.append(ops[tok](a, b))
else:
stack.append(int(tok))
return stack[0]
def _run_tests():
assert eval_rpn(["2","1","+","3","*"]) == 9
assert eval_rpn(["4","13","5","/","+"]) == 6
assert eval_rpn(["10","6","9","3","+","-11","*","/","*","17","+","5","+"]) == 22
assert eval_rpn(["3"]) == 3
assert eval_rpn(["6","2","/"]) == 3 # truncate toward zero
assert eval_rpn(["7","2","/"]) == 3 # truncate: 7/2 = 3.5 → 3
assert eval_rpn(["-7","2","/"]) == -3 # truncate toward zero: -3.5 → -3
print("all tests pass")
if __name__ == "__main__":
_run_tests()
  • Stacks, postfix evaluation is the textbook stack use case
  • Stack Parsing, the last open, first closed model for nested syntax and reversible operations.
  • Simulation, the explicit state model for executing rules exactly while keeping cases organized.