- 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.
Example
Example 1:
Input: [“2”, “1”, “+”, “3”, “"]
Output: 9
Explanation: [“2”, “1”, “+”, “3”, "”] -> (2 + 1) * 3 -> 9
Example 2:
Input: [“4”, “13”, “5”, “/”, “+”]
Output: 6
Explanation: [“4”, “13”, “5”, “/”, “+”] -> 4 + 13 / 5 -> 6
解法1:用栈。
注意:
- 只用一个栈保存数字(不能用另一个栈保存操作符)。操作符按顺序来就可以了。
- 每次如果是数字,栈pop两次,然后将两个数字按操作符类型处理,将处理的结果再放入栈中。最后返回栈顶即可。
- 数字可能为负数。
class Solution {
public:
/**
* @param tokens: The Reverse Polish Notation
* @return: the value
*/
int evalRPN(vector<string> &tokens) {
int n = tokens.size();
if (n == 0) return 0;
int result = 0;
stack<int> s;
int num1 = 0, num2 = 0;
for (int i = 0; i < n; ++i) {
if (tokens[i] != "+" && tokens[i] != "-" && tokens[i] != "*" && tokens[i] != "/") {
s.push(stoi(tokens[i]));
} else {
num1 = s.top(); s.pop();
num2 = s.top(); s.pop();
if (tokens[i] == "+") s.push(num2 + num1);
else if (tokens[i] == "-") s.push(num2 - num1);
else if (tokens[i] == "*") s.push(num2 * num1);
else s.push(num2 / num1); //note num2 != 0
}
}
result = s.top(); s.pop();
return result;
}
};
解法2:DFS。
逆波兰表达式的末尾必定是操作符,所以可从末尾开始处理:
- 遇到数字直接返回;
- 遇到操作符,向前两个位置调用递归函数,找出前面两个数字,然后进行操作将结果返回,
注意: - 一个大坑:helper()的入口参数的index必须是指针或引用。
以input=[“4”, “13”, “5”, “/”, “+”]为例:
如果index不加&,则index打印顺序为4,3,2,1,2
如果index加&,则index打印顺序为4,3,2,1,0
从trace开始分析,index不加&的情情形:
一开始index=4,调用num1=helper(tokens, 3)。
helper() //index=4
//opt = “+”
=>num1 = helper(–index); //index=4-1=3
//opt = “/”
=>num1 = helper(–index); //index = 3-1=2
=>num2 = helper(–index; //index=2-1=1
//num1 = 13/5=2
=>num2 = helper(–index); //此时仍然为index=3-1=2 出错
index加了&后,最下面的num2的index为1,所以num2=helper(0)直接返回tokens[0],结果正确。
class Solution {
public:
/**
* @param tokens: The Reverse Polish Notation
* @return: the value
*/
int evalRPN(vector<string> &tokens) {
int n = tokens.size();
if (n == 0) return 0;
n--;
return helper(tokens, n);
}
private:
bool isOperator(const string & token) {
return token.size() == 1 && string("+-*/").find(token) != string::npos;
}
int helper(vector<string> & tokens, int &index) {
//cout<<index<<endl;
string token = tokens[index];
if (!isOperator(token)) return stoi(token);
int num1 = helper(tokens, --index);
int num2 = helper(tokens, --index);
if (token == "+") return num2 + num1;
if (token == "-") return num2 - num1;
if (token == "*") return num2 * num1;
return num2 / num1;
}
};