Evaluate Reverse Polish Notation
Stack of operands — on operator, pop two, apply, push result.
3 min read
stack string parsing
Problem#
Evaluate an arithmetic expression in Reverse Polish Notation. Operators are +, -, *, / (truncated toward zero for division).
Examples#
["2","1","+","3","*"]→9((2+1)*3).["4","13","5","/","+"]→6.
Constraints#
1 <= tokens.length <= 10^4.
Approach#
Stack. Push every operand. On an operator, pop two, apply (note order: the second pop is the left operand), push the result.
Solution#
class Solution {public: int evalRPN(vector<string>& tokens) { stack<int> st; for (auto& t : tokens) { if (t == "+" || t == "-" || t == "*" || t == "/") { int b = st.top(); st.pop(); int a = st.top(); st.pop(); if (t == "+") st.push(a + b); else if (t == "-") st.push(a - b); else if (t == "*") st.push(a * b); else st.push(a / b); } else st.push(stoi(t)); } return st.top(); }};import "strconv"
func evalRPN(tokens []string) int { st := []int{} for _, t := range tokens { if t == "+" || t == "-" || t == "*" || t == "/" { b := st[len(st)-1] a := st[len(st)-2] st = st[:len(st)-2] switch t { case "+": st = append(st, a+b) case "-": st = append(st, a-b) case "*": st = append(st, a*b) case "/": st = append(st, a/b) } } else { v, _ := strconv.Atoi(t) st = append(st, v) } } return st[len(st)-1]}from typing import List
class Solution: def evalRPN(self, tokens: List[str]) -> int: st = [] for t in tokens: if t in ("+", "-", "*", "/"): b = st.pop() a = st.pop() if t == "+": st.append(a + b) elif t == "-": st.append(a - b) elif t == "*": st.append(a * b) else: # truncate toward zero st.append(int(a / b)) else: st.append(int(t)) return st[-1]function evalRPN(tokens) { const st = []; for (const t of tokens) { if (t === '+' || t === '-' || t === '*' || t === '/') { const b = st.pop(); const a = st.pop(); if (t === '+') st.push(a + b); else if (t === '-') st.push(a - b); else if (t === '*') st.push(a * b); else st.push(Math.trunc(a / b)); } else { st.push(parseInt(t, 10)); } } return st[st.length - 1];}class Solution { public int evalRPN(String[] tokens) { Deque<Integer> st = new ArrayDeque<>(); for (String t : tokens) { if (t.equals("+") || t.equals("-") || t.equals("*") || t.equals("/")) { int b = st.pop(); int a = st.pop(); switch (t) { case "+": st.push(a + b); break; case "-": st.push(a - b); break; case "*": st.push(a * b); break; default: st.push(a / b); } } else { st.push(Integer.parseInt(t)); } } return st.peek(); }}function evalRPN(tokens: string[]): number { const st: number[] = []; for (const t of tokens) { if (t === '+' || t === '-' || t === '*' || t === '/') { const b = st.pop() as number; const a = st.pop() as number; if (t === '+') st.push(a + b); else if (t === '-') st.push(a - b); else if (t === '*') st.push(a * b); else st.push(Math.trunc(a / b)); } else { st.push(parseInt(t, 10)); } } return st[st.length - 1];}Editorial#
Order of pops is b (right operand) before a (left operand) — getting this wrong silently produces wrong answers for non-commutative ops. C++ integer division already truncates toward zero, matching the problem’s spec.
Complexity#
- Time:
O(n). - Space:
O(n).
Concept revision#
Related#