---
# System prepended metadata

title: 150.  Evaluate Reverse Polish Notation
tags: [Stack, Medium, Array]

---

## Question

>[Leetcode.150 Evaluate Reverse Polish Notation
](https://leetcode.com/problems/evaluate-reverse-polish-notation/description/)

<br>

:::info
:::spoiler *Optimal Space & Time Complexity*
<br>

```
- Time complexity: O()
- Space complexity: O()
```
:::

<br>

## Thoughts & Solutions


### YC
- push the number into the stack
:::spoiler Code
```javascript=
/**
 * @param {string[]} tokens
 * @return {number}
 */
var evalRPN = function(tokens) {
    const numStack = [];
    const operators = {
        '+': (a, b) => a + b,
        '-': (a, b) => a - b,
        '*': (a, b) => a * b,
        '/': (a, b) => Math.trunc(a / b),
    };
    for(t of tokens){
        if(t in operators){
            const back = numStack.pop();
            const front = numStack.pop();
            numStack.push(operators[t](front, back));
        }else{
            numStack.push(Number(t));
        }
    }
    return numStack.pop()   
};
```
:::

<hr/>

### Sol
:::spoiler Code
```javascript=

/**
 * @param {string[]} tokens
 * @return {number}
 */
var evalRPN = function(tokens) {
    const operators = ['+','-','*','/']
    const stack = [];
    for (let i= 0; i< tokens.length ;i++ )  {
        if(!operators.includes(tokens[i])){
            stack.push(+tokens[i])
            continue;
        }
        const operand2 = stack.pop();
        const operand1 = stack.pop();
        switch(tokens[i]){
            case '+':
                stack.push(operand1 + operand2);
                break;
            case '-':
                stack.push(operand1 - operand2);
                break;
            case '*':
                stack.push(operand1 * operand2);
                break;
            case '/':
                stack.push(Math.trunc(operand1 / operand2));
                break;
        }
    }
    return stack[0];
};


```
:::

<hr/>

### 東

:::spoiler Code
```javascript=
var evalRPN = function(tokens) {
    const stack = [];
    
    for(let i =0; i < tokens.length; i++) {
	    const currChar = tokens[i];
        if(isNaN(+currChar)) {
            const secondChar = stack.pop();
            const firstChar = stack.pop();

            switch(currChar) {
                case “+”: 
                    stack.push(firstChar + secondChar);
                    break;
                case “-”: 
                    stack.push(firstChar - secondChar);
                    break;
                case “*”: 
                    stack.push(firstChar * secondChar);
                    break;
                case “/”:
                    stack.push(Math.trunc(firstChar / secondChar));
            }
	    } else {
	     stack.push(+tokens[i]);
        }
    }
	return stack[0];
}

```
:::

<hr/>

### Jessie
:::spoiler MEMO
- 先理解 Reverse Polish Notation 是啥
    - 維基百科的解釋
        - 逆波蘭記法中，運算子(符號)置於運算元(數字)的後面。
        例如表達「三加四」時，寫作「3 4 + 」，而不是「3 + 4」。
        如果有多個運算子，運算子置於第二個運算元的後面，所以常規中綴記法的「3 - 4 + 5」在逆波蘭記法中寫作「3 4 - 5 + 」：先3減去4，再加上5。
- 答案需求
    - 無條件捨去小數
    - return 最終計算結果數字即可
- 實作方向
    1. 用一個空array `stack` 依序存入遇到的數字
    2. 遇到符號的時候就丟eval()計算
        - 取出前兩個數字(排序不動)與符號計算
        - 計算完的結果無條件捨去小數位
    3. 將結果存回stack中接續下一個token走1-3這個模式
:::

```mermaid
graph TD;
subgraph INPUT
tokens("tokens = ['3', '4', '-', '5', '+']")
end

subgraph Step1
tokens1("tokens = ['3', '4', '-']")
stack1("stack = [3, 4]")
ans1(ans = 3 - 4)
	subgraph After Calculation
	ans1AfterCal(ans = -1)
	stack1AfterCal("stack = [-1]")
	end
end

subgraph Step2
tokens2("tokens = ['5', '+']")
stack2("stack = [-1, 5]")
ans2(ans = -1 + 5)
	subgraph After Calculation
	ans2AfterCal(ans = 4)
	stack2AfterCal("stack = [4]")
	end
end

INPUT --> Step1 --> Step2;
```

:::spoiler Code
```javascript=
/**
 * @param {string[]} tokens
 * @return {number}
 */
var evalRPN = function (tokens) {
  let stack = [];
  let ans;

  tokens.forEach((v, i) => {
    console.log({ i, ans, v, stack });

    //  Save number into stack
    if (isNumber(v)) return stack.push(+v);

    //  Handle symbol
    let secondNum = stack.pop();
    let firstNum = stack.pop();

    //  It's important to add () to secondNum because of the negative will cause the formula cal error
    let formula = `${firstNum}${v}(${secondNum})`;
    ans = calculateAndRoundDown(formula);
    stack.push(ans);
  });

  return tokens.length === 1 ? stack[0] : ans;
};

function isNumber(string) {
  return isNaN(+string) ? false : true;
}

function calculateAndRoundDown(formula) {
  return parseInt(eval(formula));
}
```
:::

<hr/>

### 皮皮

:::spoiler Code
```javascript=

```
:::
<br>

## Live Coding

:::spoiler (name)
```
// write your code here
```
:::


