题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。
假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
解题思路
- 由前序遍历序列确定根节点
由前序遍历序列{1,2,4,7,3,5,6,8}知根节点数值为1 - 在中序遍历序列中找到该根节点
- 中序遍历序列的根节点为分界,左边为左子树{4,7,2},右边为右子树{5,3,8,6},
求出左子树结点个数leftTreeSize=3 - 在前序遍历序列中,从根节点往后leftTreeSize个数为左子树{2,4,7},剩下为右子树{3,5,6,8}。
- 对两种序列中左子树进行递归重建,对两种序列中的右子树进行递归重建
参考代码
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
struct TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> in) {
int preOrderSize = static_cast<int> (pre.size());
int inOrderSize = static_cast<int> (in.size());
if ( preOrderSize == 0 || inOrderSize == 0 ) {
return NULL;//某结点无左边或右边叶子结点时,其左边结点或右边结点指向NULL
}
struct TreeNode* pRoot = new struct TreeNode(pre[0]);
int rootNodeIndexInInOrder = -1;
for ( int i = 0; i < inOrderSize; i++ ) {
if ( in[i] == pRoot->val ) {
rootNodeIndexInInOrder = i;//左子树结点个数
break;
}
// if ( i == inOrderSize - 1 ) {
// throw std::exception("Invalid input!");
// }
}
int nodeNumberLeft = rootNodeIndexInInOrder;
vector<int> preOrderLeft;
vector<int> preOrderRight;
for ( int i = 0; i < preOrderSize-1; i++ ) {
if ( i < nodeNumberLeft ) {
preOrderLeft.push_back(pre[i+1]);
} else {
preOrderRight.push_back(pre[i+1]);
}
}
vector<int> inOrderLeft;
vector<int> inOrderRight;
for ( int i = 0; i < nodeNumberLeft; i++ ) {
if ( i < nodeNumberLeft ) {
inOrderLeft.push_back(in[i]);
}
}
for ( int i = nodeNumberLeft+1; i < inOrderSize; i++ ) {
inOrderRight.push_back(in[i]);
}
pRoot->left = reConstructBinaryTree(preOrderLeft, inOrderLeft);
pRoot->right = reConstructBinaryTree(preOrderRight, inOrderRight);
return pRoot;
}
};