# LeetCode – Evaluate Reverse Polish Notation

Evaluate the value of an arithmetic expression in Reverse Polish Notation. Valid operators are +, -, *, /. Each operand may be an integer or another expression. For example:

```  ["2", "1", "+", "3", "*"] -> ((2 + 1) * 3) -> 9
["4", "13", "5", "/", "+"] -> (4 + (13 / 5)) -> 6
```

1. Naive Approach

This problem can be solved by using a stack. We can loop through each element in the given array. When it is a number, push it to the stack. When it is an operator, pop two numbers from the stack, do the calculation, and push back the result. The following is the code. However, this code contains compilation errors in leetcode. Why?

```public class Test {   public static void main(String[] args) throws IOException { String[] tokens = new String[] { "2", "1", "+", "3", "*" }; System.out.println(evalRPN(tokens)); }   public static int evalRPN(String[] tokens) { int returnValue = 0; String operators = "+-*/";   Stack<String> stack = new Stack<String>();   for (String t : tokens) { if (!operators.contains(t)) { //push to stack if it is a number stack.push(t); } else {//pop numbers from stack if it is an operator int a = Integer.valueOf(stack.pop()); int b = Integer.valueOf(stack.pop()); switch (t) { case "+": stack.push(String.valueOf(a + b)); break; case "-": stack.push(String.valueOf(b - a)); break; case "*": stack.push(String.valueOf(a * b)); break; case "/": stack.push(String.valueOf(b / a)); break; } } }   returnValue = Integer.valueOf(stack.pop());   return returnValue; } }```

The problem is that switch string statement is only available from JDK 1.7. Leetcode apparently use a JDK version below 1.7.

2. Accepted Solution

If you want to use switch statement, you can convert the above by using the following code which use the index of a string "+-*/".

```public class Solution { public int evalRPN(String[] tokens) {   int returnValue = 0;   String operators = "+-*/";   Stack<String> stack = new Stack<String>();   for(String t : tokens){ if(!operators.contains(t)){ stack.push(t); }else{ int a = Integer.valueOf(stack.pop()); int b = Integer.valueOf(stack.pop()); int index = operators.indexOf(t); switch(index){ case 0: stack.push(String.valueOf(a+b)); break; case 1: stack.push(String.valueOf(b-a)); break; case 2: stack.push(String.valueOf(a*b)); break; case 3: stack.push(String.valueOf(b/a)); break; } } }   returnValue = Integer.valueOf(stack.pop());   return returnValue;   } }```
Category >> Algorithms
If you want someone to read your code, please put the code inside <pre><code> and </code></pre> tags. For example:
```<pre><code>
String foo = "bar";
</code></pre>
```
• Rahul Jain

Hi guys,
I created a small video explaining the stack data structure logic . Please check, any suggestions are welcome 🙂

• Ashish Kumar Sahu

can someone help me
i wrote this program using python
l=[]
a=int(input())
for i in range(a):
b=input()
l.append(b)
for i in range(len(l)):
if(l[i]==’+’):
l[i]=l[i-2]+l[i-1]
l[i-2:i]=[]
elif (l[i]==’-‘):
l[i]=l[i-2]-l[i-1]
l[i-2:i]=[]
elif (l[i]==’*’):
l[i]=l[i-2]*l[i-1]
l[i-2:i]=[]
elif (l[i]==’/’):
l[i]=l[i-2]/l[i-1]
l[i-2:i]=[]
else:
l[i]=int(l[i])
print(l)
i got an error
Traceback (most recent call last):
File “__tester__.python3”, line 7, in
if(l[i]==’+’):
IndexError: list index out of range
pls explain where i made a mistake

• Your comments are misleading. The second pop is left operand only. see division is (b/a) where b is second pop. if stack does not have a and b then the pop() itself will error out.

• Cat Racket
• // Recursive approach

private static int reversePolishNotation(String[] arr) {
if (arr.length == 3) {
int a = Integer.parseInt(arr);
int b = Integer.parseInt(arr);
return calculate(a, b, arr);
} else if (arr.length > 3) {
String[] temp = new String[arr.length – 2];
int a = Integer.parseInt(arr);
int b = Integer.parseInt(arr);
int c = calculate(a, b, arr);

temp = c + “”;

for (int i = 3; i < arr.length; ++i) {
temp[i – 2] = arr[i];
}

return reversePolishNotation(temp);
} else {
throw new IllegalArgumentException("wrong array input!");
}
}

private static int calculate(int a, int b, String operator) {
switch (operator) {
case "+":
return a + b;
case "-":
return a – b;
case "*":
return a * b;
case "/":
return a / b;
default:
throw new IllegalStateException("Oops!");
}
}

• PraveenKumar Subramanian

Division by zero is not checked.

• sam

Because it is mentioned in question that “operand may be an integer or another expression”. So it is assumed to be integer.

• ANAND

public static void main(String[] args) {
String s[]={“2”, “1”, “+”, “3”, “*”};
Stack stack = new Stack();
for(int i=0;i<s.length;i++){
if(isoperator(s[i])){
int num1=Integer.valueOf(stack.pop());
int num2=Integer.valueOf(stack.pop());
switch (s[i]) {
case "+":
stack.push(String.valueOf(num1+num2));
break;
case "*":
stack.push(String.valueOf(num1*num2));
break;
case "-":
stack.push(String.valueOf(num1-num2));
break;
default:
stack.push(String.valueOf(num1/num2));
break;
}
}else{
stack.push(s[i]);
}
}
System.out.println(stack.pop());

}
public static boolean isoperator(String s){
if(s=="*"||s=="+"||s=="/"||s=="-"){
return true;
}
return false;
}

• Brikesh Kumar

``` public static void Main(string[] args) { //Your code goes here //reverse polish notation string[] input = new string[] {"2", "1", "+", "3", "*"}; Stack stack = new Stack(); int result = 0; for(int i = 0; i < input.Length; i++){ int number; if (int.TryParse(input[i],out number)){ stack.Push(number); } else{ if (input[i] == "+"){ var item1 = stack.Pop(); var item2 = stack.Pop(); result = item1 + item2; stack.Push(result); } if(input[i] == "*"){ var item1 = stack.Pop(); var item2 = stack.Pop(); result = item1 * item2; stack.Push(result); } //Add more maths notations } } Console.WriteLine(result);```

``` ```

``` } ```

• LegoMushroom

Designed the algorithm with constant space complexity O(1)! Linear time complexity O(n).

https://discuss.leetcode.com/topic/67582/accepted-the-best-complexity-o-n-time-o-1-space-well-explained-javascript

• emirpolo

JavaScript

function ReversePolishNotation(ain) {
var out = [];
ain.forEach(function(o){
if(!isNaN(o)) {
out.push(o);
}
else {
var a = out.pop();
var b = out.pop();
out.push(eval(b + o + a));
}
});
return out.pop();
}

• Greg Mueller

Thanks Ryan, I tried this and found an error – in eval_op, you are missing the ‘:’ before each return. Also you named your main function ‘eval’, which overwrites the built-in eval function.

I refactored your code down to this. The main difference is that I am building a string that looks like Python code and then calling eval on that string. Also, I am storing the numbers as strings, since I am not forcing the intergers to flow, or float to integer.

``` def rpn(expr): s = [] expr = expr.split() if type(expr) == type('') else expr for item in expr: if item.isnumeric(): s.append(int(item)) elif item in {'+', '-', '*', '/'}: intermediate_expr = ' '.join((str(s.pop()), item, str(s.pop()))) s.append(eval(intermediate_expr)) else: raise ValueError('Invalid value: ' + item) return s.pop()```

``` ```

```rpn('4 13 5 / +') rpn(["2", "1", "+", "3", "*"]) ```

• bimal prasad pandey

thanx for it

• Ryan Shaw

Python solution:
``` def eval_op(land, rand, op): if (op == '-') return land - rand if (op == '+') return land + rand if (op == '/') return land / rand if (op == '*') return land * rand raise ValueError('unrecognized op: ' + op)```

``` def is_op(c): return c == '+' or c == '-' or c == '*' or c == '/' ```

```def eval(expr): s = [] for c in expr: if not is_op(c): s.append(int(c)) else: rand, land = s.pop(), s.pop() s.append(eval_op(land, rand, c)) return s.pop() ```

• Abhishek Roy

This may be due to lowercase “s” in “string”. Try using “String” instead of “string” as shown below,
Stack stack = new Stack();

• srj_michael

` `

``` ```

` Stack stack = new Stack();`
Showing error as :type stack does not take parameter

• srj_michael

It’s showing error.
error: type stack does not take parameter.

• Yunxiao Zou

naive approach works for current Leetcode Java OJ

• Taylor Annaterre
• meha

I was evaluating the second eg. i.e [“4”, “13”, “5”, “/”, “+”] -> (4 + (13 / 5)) -> 6 and solution is 4 instead of 6, because you pop 5 and then 13 ==> which will give you 5/13 =0 and hence the expression will result in 4.

• Parag Chaudhari

There is a bug in this code, first pop() must be a right operand and second pop() must be a left operand.

Also, include following Edge Cases:
1. You should check before returning that stack contains only one element.
2. You must check divide by zero error for division operation
3. You must handle unary operators e.g. factorial (!)
4. Before performing any binary operation you must check whether stack has 2 operands.
5. Before performing any unary operation you must check whether stack has 1 operand.

• anonymous

Here it is in Ruby if anyone is curious:

def evaluate(expression)
stack = []
until expression.empty?
a = expression.shift
if (a.eql?(“+”) || a.eql?(“*”) || a.eql?(“-“) || a.eql?(“/”))
x, y = stack.pop, stack.pop
stack.push y.send(a, x)
else
stack.push a.to_i
end
end
stack.first
end
evaluate [“4”, “13”, “5”, “/”, “+”]
#=> 6

• cg22165

Better to use a Stack of Integers. Boxing and unboxing should be more efficient than creating and garbage collecting a lot of Strings.

Better to wrap most of the operation and data type conversions in a try-catch. The catch can simply return “Data error”, “Invalid expression”, or similar.

The pop of a and b should be reversed. “0 1 /” is valid, but “1 0 /” is an error.

Honey badger doesn’t care whether you use ints, doubles, bigdecimals, whatever. They are looking for a good algorithm.

• sebastian

always a and b will be an int ? dont you think that maybe b could be null ? and in this case you wil have problems with the operations.

• ryanlr

It does not belong here, and can you put the code inside <pre> tags?

• Salil Surendran

What do you guys think of this solution. This is an O(n) solution

private String findLongestPalindromicSubString(String str){

if(str == null || str.length() == 0)
return null;
else if(str.length() == 1)
return str;
else{
//Traverse down the string and which is each character
//check this logic.
int index=1;
String longestPalindrome=null;
while(index < str.length()/*||
(longestPalindrome != null && str.length() – index 2 && str.charAt(index) == str.charAt(index – 2))
currentPalindrome=readPalindrome(index – 2, index, str);

if(currentPalindrome != null){
if(longestPalindrome == null || currentPalindrome.length() > longestPalindrome.length())
longestPalindrome=currentPalindrome;
index+=currentPalindrome.length() / 2;
}else
index++;
}
return longestPalindrome;
}
}

• I also don’t understand why the accepted solution uses Integer, it should use Double or at least Float.

• Julien Dreux

This implementation makes wrong assumptions about the pop/push methods on arrays. Pop and push act at the end of the array, the shift and unshift methods should be used instead.

• themansitiwari

what if we want the user to give in the input? like what if we have two digit or three digit numbers separated by comma or space?

• Dongyon Kang

wouldn’t b/a return an integer, which could be incorrect in cases such as “1/2” since b and a are both ints?

The problem presented above is for a reverse polish notation (or postfix notation).
The problem you describe is in standard infix format. Postfix notation always assumes you have two operands preceding an operator. Thus your case doesn’t really apply. You could, however, make an error check for special cases that fall beyond the method’s assumptions. For example 2* would be 2 *1, or 2 *0, whatever you deem fit.

• codingfacts

• Henco Appel

Thought I’d point out something slightly nicer than using the index, in Java 1.6 you can switch on chars, so why not just switch on t.charAt(0) for cases ‘+’, ‘-‘, ‘*’, ‘/’. Also means that you don’t have to do a search, even though it’s only a String of 4 characters.

• Henco Appel

The hole point of RPN is that you don’t need the brackets, the order of the numbers and operators is what defines the order of the operations, so no need for brackets or BODMAS.

• shreyas KN

hey are we not supposed to apply the BODMAS rules here ?

• ryanlr

Changed. Thanks!

• JeffreyT

for the naive solution, you may want to replace “a – b” with “b – a” in case “-” of switch block.