04.17 重建二叉树
Posted 少年仗剑行
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了04.17 重建二叉树相关的知识,希望对你有一定的参考价值。
题目:
示例:
preorder:
[3,9,20,15,7]
inorder:
[9,3,15,20,7]
return:
3
/ \
9 20
/ \
15 7
限制:
0 <= 节点个数 <= 5000
方法1:
class Solution {
public:
map<int, int> index;
TreeNode* build(vector<int>& preorder, vector<int>& inorder, int preLeft, int preRight, int inLeft, int inRight) {
if(preLeft > preRight) // 树节点为空
return NULL;
int rootIn = index[preorder[preLeft]]; // 定位中序遍历的根节点
int sizeLeft = rootIn - inLeft; // 获得左子树的节点数目
TreeNode* root = new TreeNode(preorder[preLeft]); // 构造根节点
root->left = build(preorder, inorder, preLeft + 1, preLeft + sizeLeft, inLeft, rootIn - 1); // 构造左子树
root->right = build(preorder, inorder, preLeft + sizeLeft + 1, preRight, rootIn + 1, inRight); // 构造右子树
return root;
}
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
int n = inorder.size();
for(int i = 0; i < n; i++) {
index[inorder[i]] = i; // 构造映射,用于定位根结点
}
return build(preorder, inorder, 0, n-1, 0, n-1);
}
};
方法2:
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
// 利用前序遍历和中序遍历的差异,分辨出前序遍历的左子树和右子树
if(!preorder.size()) // 树节点为空
return NULL;
TreeNode* root = new TreeNode(preorder[0]); // 构造根节点
stack<TreeNode*> nodes; // 使用栈存储树节点
nodes.push(root);
int inorderIndex = 0;
for(int i = 1; i < preorder.size(); i++) {
if(nodes.top() -> val != inorder[inorderIndex]) { // 前序遍历左子树
nodes.top() -> left = new TreeNode(preorder[i]); // 将左子树加入到根节点
nodes.push(nodes.top() -> left);
}
else { // 前序遍历右子树
TreeNode* node; // 记录右子树的根节点
while(!nodes.empty() && nodes.top() -> val == inorder[inorderIndex]) {
node = nodes.top();
nodes.pop();
inorderIndex++;
}
node->right = new TreeNode(preorder[i]); // 将右子树加入到根节点
nodes.push(node -> right);
}
}
return root;
}
};
以上是关于04.17 重建二叉树的主要内容,如果未能解决你的问题,请参考以下文章