- Expression Tree Build
The structure of Expression Tree is a binary tree to evaluate certain expressions.
All leaves of the Expression Tree have an number string value. All non-leaves of the Expression Tree have an operator string value.
Now, given an expression array, build the expression tree of this expression, return the root of this expression tree.
Example
Example 1:
Input: [“2”,"",“6”,"-","(",“23”,"+",“7”,")","/","(",“1”,"+",“2”,")"]
Output: {[-],[],[/],[2],[6],[+],[+],#,#,#,#,[23],[7],[1],[2]}
Explanation:
The expression tree will be like
[ - ]
/ \
[ * ] [ / ]
/ \ / \
[ 2 ] [ 6 ] [ + ] [ + ]
/ \ / \
[ 23 ][ 7 ] [ 1 ] [ 2 ] .
After building the tree, you just need to return root node [-]
.
Example 2:
Input: [“10”,"+","(",“3”,"-",“5”,")","+",“7”,"",“7”,"-",“2”]
Output: {[-],[+],[2],[+],[],#,#,[10],[-],[7],[7],#,#,[3],[5]}
Explanation:
The expression tree will be like
[ - ]
/
[ + ] [ 2 ]
/ \
[ + ] [ * ]
/ \ /
[ 10 ] [ - ] [ 7 ] [ 7 ]
/ \
[3] [5]
After building the tree, you just need to return root node [-]
.
Clarification
See wiki:
Expression Tree
这题很难,下面两种解法都是参考自网上。
解法1:转换成逆波兰表达式,然后再递归找出root。
代码如下:
/**
* Definition of ExpressionTreeNode:
* class ExpressionTreeNode {
* public:
* string symbol;
* ExpressionTreeNode *left, *right;
* ExpressionTreeNode(string symbol) {
* this->symbol = symbol;
* this->left = this->right = NULL;
* }
* }
*/
class Solution {
public:
/**
* @param expression: A string array
* @return: The root of expression tree
*/
int getLevel(string opt) {
if (opt == "(")
return 0;
if (opt == "+" || opt == "-")
return 1;
if (opt == "*" || opt == "/")
return 2;
return 3;
}
bool isOperator(string c) {
return (c == "+" || c == "-" || c == "*" || c == "/");
}
//create reverse polish notation string
vector<string> convertToRPN(vector<string> &expression) {
stack<string> st;
vector<string> RPN;
int len = expression.size();
for (int i = 0; i < len; ++i) {
string c = expression[i];
if (c == "(")
st.push(c);
else if (c == ")") {
while (st.top() != "(") {
RPN.push_back(st.top());
st.pop();
}
st.pop();
} else {
if (!isOperator(c))
st.push(c);
else {
while (!st.empty() && getLevel(st.top()) >= getLevel(c)) {
RPN.push_back(st.top());
st.pop();
}
st.push(c);
}
}
}
while (! st.empty()) {
RPN.push_back(st.top());
st.pop();
}
return RPN;
}
ExpressionTreeNode* build(vector<string> &expression) {
vector<string> RPN = convertToRPN(expression);
int len = RPN.size();
stack<ExpressionTreeNode *> nodeStack;
for (int i = 0; i < len; ++i) {
string s = RPN[i];
ExpressionTreeNode *pNode = new ExpressionTreeNode(s);
if (s == "+" || s == "-" || s == "*" || s == "/") {
ExpressionTreeNode *pRight = nodeStack.top();
nodeStack.pop();
ExpressionTreeNode *pLeft = nodeStack.top();
nodeStack.pop();
pNode->right = pRight;
pNode->left = pLeft;
nodeStack.push(pNode);
} else
nodeStack.push(pNode);
}
if (nodeStack.empty())
return NULL;
else
return nodeStack.top();
}
};
解法2:生成min-tree,然后用单调递减栈(栈底到栈底单调递减)。
代码如下:
/**
* Definition of ExpressionTreeNode:
* class ExpressionTreeNode {
* public:
* string symbol;
* ExpressionTreeNode *left, *right;
* ExpressionTreeNode(string symbol) {
* this->symbol = symbol;
* this->left = this->right = NULL;
* }
* }
*/
class MyTreeNode {
public:
int val;
ExpressionTreeNode * eNode;
MyTreeNode(int v = 0, string s = ""){
val = v;
eNode = new ExpressionTreeNode(s);
}
};
class Solution {
public:
/**
* @param expression: A string array
* @return: The root of expression tree
*/
ExpressionTreeNode* build(vector<string> & expression) {
if (expression.size() == 0) {
return NULL;
}
stack<MyTreeNode *> stk;
int base = 0;
int val = 0;
for (int i = 0; i < expression.size(); i++) {
if (expression[i] == "(") {
base += 10;
continue;
}
if (expression[i] == ")") {
base -= 10;
continue;
}
val = getWeight(base, expression[i]);
MyTreeNode * node = new MyTreeNode(val, expression[i]);
while (!stk.empty() && node->val <= stk.top()->val) {
node->eNode->left = stk.top()->eNode;
stk.pop();
}
if (!stk.empty()) {
stk.top()->eNode->right = node->eNode;
}
stk.push(node);
}
if (stk.empty()) {
return NULL;
}
MyTreeNode * rst = stk.top();
stk.pop();
while (!stk.empty()) {
rst = stk.top();
stk.pop();
}
return rst->eNode;
}
private:
//Calculate weight for characters
int getWeight(int base, string s) {
if (s == "+" || s == "-") {
return base + 1;
}
if (s == "*" || s == "/") {
return base + 2;
}
return INT_MAX;
}
};