题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
样例
例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
算法1
(递归重建) $O(nlogn)$
前序遍历的第一个节点为根节点,根据根节点的值在中序遍历中找到其对应位置,左边是左子树,右边是右子树,然后左右递归求解即可。
时间复杂度
每次在中序遍历中查找根节点的位置需要$O(n)$的时间,则复杂度总共为$2 * T(n / 2) + O(1) + O(n)$,也就是$O(nlogn)$。
C++ 代码
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if(preorder.empty() || inorder.empty() || preorder.size() != inorder.size()){
return NULL;
}
int index;
vector<int> leftPre, rightPre, leftVin, rightVin;
TreeNode* root = new TreeNode(preorder[0]);
for(int i = 0; i < inorder.size(); i++) //找出根节点位置
{
if(inorder[i] == preorder[0])
{
index = i;
break;
}
}
for(int i = 0; i < index; i++){//判断根节点左边的情况
leftPre.push_back(preorder[i+1]); ////第一个为根根节点,跳过
leftVin.push_back(inorder[i]);
}
for(int i = index+1; i < inorder.size(); i++){//判断根节点左边的情况
rightPre.push_back(preorder[i]);
rightVin.push_back(inorder[i]);
}
root->left = buildTree(leftPre, leftVin);
root->right = buildTree(rightPre, rightVin);
return root;
}
};