## 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 ``` :::