题目
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
思路
前序序列是 根->左->右;中序序列是 左->根->右;已知二叉树的前序序列和中序序列,求二叉树的结构:
所以通过二叉树的前序序列来找出该二叉树的根节点,这个根节点在中序序列中的位置将该二叉树分为左子树和右子树,得到左子树的中序序列和右子树的中序序列,从而得到左子树的长度,根据左子树的长度截取出左子树的前序序列(原前序序列根节点后面第一段),剩余部分为右子树前序序列(原前序序列根节点后面第二段)。此时我们得到了左子树的前序序列和中序序列,右子树的前序序列和中序序列,可以对左子树和右子树又迭代进行上述过程,重建二叉树.
代码
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
if (pre.empty())
{
return NULL;
}
TreeNode* p = new TreeNode(pre[0]); //前序序列第一个数为根结点
if (pre.size() == 1)
{
return p;
}
int root = pre[0];
int flag;
vector<int> left_pre, right_pre, left_vin, right_vin;
//TreeNode* p = new TreeNode(pre[0]); //前序序列第一个数为根结点
//pre.erase(pre.begin() + 0);
//flag = lower_bound(vin.begin(), vin.end(), root)-vin.begin();
for (int i = 0; i < vin.size(); i++) //根节点的中序序列下标
{
if (vin[i] == root)
{
flag = i;
break;
}
}
for (int i = 0; i < flag; i++) //更新左右中序序列
left_vin.push_back(vin[i]);
for (int i = flag + 1; i < vin.size(); i++)
right_vin.push_back(vin[i]);
for (int i = 1; i < flag+1; i++) //更新左右前序序列
left_pre.push_back(pre[i]);
for (int i = flag + 1; i < pre.size(); i++)
right_pre.push_back(pre[i]);
p->left = reConstructBinaryTree(left_pre, left_vin); //更新根节点的左孩子,迭代
p->right = reConstructBinaryTree(right_pre, right_vin); //更新根节点的右孩子,迭代
return p;
}
};