题目
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
思路
- 前序遍历,遍历顺序根节点,左子树,右子树。
- 中序遍历,遍历顺序左子树,根节点,右子树。
- 所以,对于给定的前序序列pre, 它的第一个元素就是整棵树的根节点。
- 在给定的中序序列vin中,找到上一步得到的根节点,则该节点左边的部分属于左子树,右边的部分属于右子树。
- 得到一个根节点之后,递归得到左右子树。对于左右子树对应的前序、中序序列,仍然具有上述性质,所以递归的得到左右子树。
代码一
/**
* 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* helper( vector<int>& pre, int pStart, int pEnd,
vector<int>& vin, int vStart, int vEnd ) {
if ( pStart > pEnd ) return nullptr;
TreeNode* node = new TreeNode( pre[pStart] );
if ( pStart == pEnd ) return node;
// 找到在中序的位置
int pos = vStart;
while ( vin[pos] != pre[pStart] ) {
++pos;
}
node->left = helper( pre, pStart+1, pStart+pos-vStart,
vin, vStart, pos-1);
node->right = helper( pre, pStart+pos-vStart+1, pEnd,
vin, pos+1, vEnd);
return node;
}
TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
return helper( pre, 0, pre.size()-1, vin, 0, vin.size()-1 );
}
};
代码二
- 代码一的参数较多,思想直观,但是看着比较不直观。
- 一种直观的方法是创建四个数组leftPre, rightPre,leftIn, rightIn分别保存前序和中序序列中,属于左右子树的部分。
- 然后把这四个数组进行递归传递。
- 当数组为空时,返回空指针。
/**
* 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) {
int length = pre.size();
if (length == 0)
return NULL;
vector<int> leftPre, rightPre;
vector<int> leftIn, rightIn;
TreeNode* root = new TreeNode(pre[0]);
// 中序遍历序列中找到root
int rootIndex = -1;
for (int i = 0; i < length; i++)
{
if (vin[i] == pre[0])
{
rootIndex = i;
break;
}
}
// 左子树序列
for (int i = 0; i < rootIndex; i++)
{
leftPre.push_back(pre[i + 1]);
leftIn.push_back(vin[i]);
}
// 右子树序列
for (int i = rootIndex + 1; i < length; i++)
{
rightPre.push_back(pre[i]);
rightIn.push_back(vin[i]);
}
root->left = reConstructBinaryTree(leftPre, leftIn);
root->right = reConstructBinaryTree(rightPre, rightIn);
return root;
}
};