1.題目
題目地址(150. 逆波蘭表示式求值 - 力扣(LeetCode))
https://leetcode.cn/problems/evaluate-reverse-polish-notation/
題目描述
給你一個字串陣列 tokens
,表示一個根據 逆波蘭表示法 表示的算術表示式。
請你計算該表示式。返回一個表示表示式值的整數。
注意:
- 有效的算符為
'+'
、'-'
、'*'
和'/'
。 - 每個運算元(運算物件)都可以是一個整數或者另一個表示式。
- 兩個整數之間的除法總是 向零截斷 。
- 表示式中不含除零運算。
- 輸入是一個根據逆波蘭表示法表示的算術表示式。
- 答案及所有中間計算結果可以用 32 位 整數表示。
示例 1:
輸入:tokens = ["2","1","+","3","*"] 輸出:9 解釋:該算式轉化為常見的中綴算術表示式為:((2 + 1) * 3) = 9
示例 2:
輸入:tokens = ["4","13","5","/","+"] 輸出:6 解釋:該算式轉化為常見的中綴算術表示式為:(4 + (13 / 5)) = 6
示例 3:
輸入:tokens = ["10","6","9","3","+","-11","*","/","*","17","+","5","+"] 輸出:22 解釋:該算式轉化為常見的中綴算術表示式為: ((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
提示:
1 <= tokens.length <= 104
tokens[i]
是一個算符("+"
、"-"
、"*"
或"/"
),或是在範圍[-200, 200]
內的一個整數
逆波蘭表示式:
逆波蘭表示式是一種字尾表示式,所謂字尾就是指算符寫在後面。
- 平常使用的算式則是一種中綴表示式,如
( 1 + 2 ) * ( 3 + 4 )
。 - 該算式的逆波蘭表示式寫法為
( ( 1 2 + ) ( 3 4 + ) * )
。
逆波蘭表示式主要有以下兩個優點:
- 去掉括號後表示式無歧義,上式即便寫成
1 2 + 3 4 + *
也可以依據次序計算出正確結果。 - 適合用棧操作運算:遇到數字則入棧;遇到算符則取出棧頂兩個數字進行計算,並將結果壓入棧中
2.題解
2.1 棧
思路
注意逆波蘭式(字尾表示式是嚴格遵循優先順序計算的,已經對於括號進行過了處理,我們只要讀兩個數,一個符號直接計算即可,不需要考慮符號優先順序)
程式碼
- 語言支援:C++
C++ Code:
class Solution {
public:
int evalRPN(vector<string>& tokens) {
unordered_map<string,function<int(int,int)>> map={
{"+",[](int a,int b){return a+b;}},
{"-",[](int a,int b){return a-b;}},
{"*",[](int a,int b){return a*b;}},
{"/",[](int a,int b){return a/b;}}
} ;
stack<int> st;
for(string& s:tokens)
{
if(map.count(s))
{
int right=st.top();st.pop();
int left=st.top();st.pop();
st.push(map[s](left,right));
}
else
st.push(stoi(s));
}
return st.top();
}
};
複雜度分析
令 n 為陣列長度。
- 時間複雜度:\(O(n)\)
- 空間複雜度:\(O(n)\)