105.从前序与中序遍历序列构造二叉树 (Medium)*
题目描述*
根据一棵树的前序遍历与中序遍历构造二叉树。你可以假设树中没有重复的元素。
示例*
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:
3
/ \
9 20
/ \
15 7
代码*
通过先序遍历确定根节点,通过中序遍历划分左右子树,递归建树。
class Solution {
public:
TreeNode *build(vector<int>& preorder, int rootPos, vector<int>& inorder, int start, int end,
unordered_map<int, int>& posMap) {
if(start > end) {
return nullptr;
}
TreeNode *root = new TreeNode(preorder[rootPos]);
int pos = posMap[preorder[rootPos]];
root->left = build(preorder, rootPos + 1, inorder, start, pos - 1, posMap);
root->right = build(preorder, rootPos + pos - start + 1, inorder, pos + 1, end, posMap);
return root;
}
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if(preorder.size() == 0) {
return nullptr;
}
unordered_map<int, int> posMap;
for(int i = 0; i < inorder.size(); i++) {
posMap[inorder[i]] = i;
}
return build(preorder, 0, inorder, 0, inorder.size() - 1, posMap);
}
};
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if(preorder.size() == 0) {
return nullptr;
}
stack<TreeNode*> helpStack;
TreeNode *root = new TreeNode(preorder[0]);
helpStack.push(root);
// i 为前序序号,j 为中序序号
for(int i = 1, j = 0; i < preorder.size(); i++) {
TreeNode *back = nullptr, *cur = new TreeNode(preorder[i]);
while(!helpStack.empty() && helpStack.top()->val == inorder[j]) {
back = helpStack.top();
helpStack.pop();
j++;
}
if(back == nullptr) {
helpStack.top()->left = cur;
}else {
back->right = cur;
}
helpStack.push(cur);
}
return root;
}
};
最后更新: July 23, 2022