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


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.

根據(jù)逆波蘭表示法,求表達(dá)式的值。

有效的運(yùn)算符包括 +, -, *, / 。每個(gè)運(yùn)算對象可以是整數(shù),也可以是另一個(gè)逆波蘭表達(dá)式。

說明:

  • 整數(shù)除法只保留整數(shù)部分。
  • 給定逆波蘭表達(dá)式總是有效的。換句話說,表達(dá)式總會(huì)得出有效數(shù)值且不存在除數(shù)為 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:

▉ 算法思路

仔細(xì)觀察上述的逆波蘭表達(dá)式,可以發(fā)現(xiàn)一個(gè)規(guī)律就是每遇到一個(gè)操作符,就將操作符前的兩個(gè)操作數(shù)進(jìn)行運(yùn)算,將結(jié)果保存到原位置。

1)我們可以將這個(gè)過程用棧來進(jìn)行操作。

2)所有的操作數(shù)都執(zhí)行近棧操作,當(dāng)遇到操作符時(shí),在棧中取出兩個(gè)操作數(shù)進(jìn)行計(jì)算,然后再將其壓入棧內(nèi),繼續(xù)遍歷數(shù)組元素,直到遍歷完整個(gè)數(shù)組為止。

3)到最后,棧內(nèi)只剩下一個(gè)數(shù),那就是最后的結(jié)果。

▉ 注意事項(xiàng)

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

1)數(shù)組中的是字符串類型,要進(jìn)行數(shù)據(jù)類型轉(zhuǎn)換 parseInt()

2)兩個(gè)操作數(shù)進(jìn)行運(yùn)算時(shí),第二個(gè)出棧的操作數(shù)在前,第一個(gè)出棧的操作數(shù)在后(注意除法)。

3)對于浮點(diǎn)型數(shù)據(jù),只取小數(shù)點(diǎn)之前的整數(shù)。

4)關(guān)于負(fù)的浮點(diǎn)型(尤其是 0 點(diǎn)幾 ),要取 0 絕對值 0 ,或直接轉(zhuǎn)化為整數(shù)。

▉ 代碼實(shí)現(xiàn)
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 提交您其他語言的代碼。在倉庫上堅(jiān)持和小伙伴們一起打卡,共同完善我們的開源小倉庫!
Github:https://github.com/luxiangqiang/JS-LeetCode

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容