LeetCode 之 JavaScript 解答第150題 —— 逆波蘭表示式求值(Evaluate Reverse Polish Notation)

不甘平凡的小鹿發表於2019-04-15

Time:2019/4/14
Title: Evaluate Reverse Polish Notation
Difficulty: Medium
Author:小鹿


題目: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.

Note:

  • Division between two integers should truncate toward zero.
  • The given RPN expression is always valid. That means the expression would always evaluate to a result and there won't be any divide by zero operation.

根據逆波蘭表示法,求表示式的值。

有效的運算子包括 +, -, *, / 。每個運算物件可以是整數,也可以是另一個逆波蘭表示式。

說明:

  • 整數除法只保留整數部分。
  • 給定逆波蘭表示式總是有效的。換句話說,表示式總會得出有效數值且不存在除數為 0 的情況。

Example 1:

Input: ["2", "1", "+", "3", "*"]
Output: 9
Explanation: ((2 + 1) * 3) = 9
複製程式碼

Example 2:

Input: ["4", "13", "5", "/", "+"]
Output: 6
Explanation: (4 + (13 / 5)) = 6
複製程式碼

Example 3:

Input: ["10", "6", "9", "3", "+", "-11", "*", "/", "*", "17", "+", "5", "+"]
Output: 22
Explanation: 
  ((10 * (6 / ((9 + 3) * -11))) + 17) + 5
= ((10 * (6 / (12 * -11))) + 17) + 5
= ((10 * (6 / -132)) + 17) + 5
= ((10 * 0) + 17) + 5
= (0 + 17) + 5
= 17 + 5
= 22
複製程式碼

Solve:

▉ 演算法思路

仔細觀察上述的逆波蘭表示式,可以發現一個規律就是每遇到一個操作符,就將操作符前的兩個運算元進行運算,將結果儲存到原位置。

1)我們可以將這個過程用棧來進行操作。

2)所有的運算元都執行近棧操作,當遇到操作符時,在棧中取出兩個運算元進行計算,然後再將其壓入棧內,繼續遍歷陣列元素,直到遍歷完整個陣列為止。

3)到最後,棧內只剩下一個數,那就是最後的結果。

▉ 注意事項

雖然過程很好理解,程式碼寫起來很簡單,但是想把演算法寫的全面還是需要考慮到很多方面的。

1)陣列中的是字串型別,要進行資料型別轉換 parseInt()

2)兩個運算元進行運算時,第二個出棧的運算元在前,第一個出棧的運算元在後(注意除法)。

3)對於浮點型資料,只取小數點之前的整數。

4)關於負的浮點型(尤其是 0 點幾 ),要取 0 絕對值 0 ,或直接轉化為整數。

▉ 程式碼實現
var evalRPN = function(tokens) {
   // 宣告棧
    let stack = [];
    for(let item of tokens){
        switch(item){
            case '+':
                let a1 = stack.pop();
                let b1 = stack.pop();
                stack.push(b1 + a1);
                break;
            case '-':
                let a2 = stack.pop();
                let b2 = stack.pop();
                stack.push(b2 - a2);
                break;
            case '*':
                let a3 = stack.pop();
                let b3 = stack.pop();
                stack.push(b3 * a3);
                break;
            case '/':
                let a4 = stack.pop();
                let b4 = stack.pop();
                stack.push(parseInt(b4 / a4));
                break;
            default: 
                stack.push(parseInt(item));
        }
    }
    return parseInt(stack.pop());
};
複製程式碼


歡迎一起加入到 LeetCode 開源 Github 倉庫,可以向 me 提交您其他語言的程式碼。在倉庫上堅持和小夥伴們一起打卡,共同完善我們的開源小倉庫! Github:https://github.com/luxiangqiang/JS-LeetCode
歡迎關注我個人公眾號:「一個不甘平凡的碼農」,記錄了自己一路自學程式設計的故事。

相關文章