「这是我参与11月更文挑战的第18天,活动详情查看:2021最后一次更文挑战」
106. 从中序与后序遍历序列构造二叉树
题目描述
根据一棵树的中序遍历与后序遍历构造二叉树。
注意: 你可以假设树中没有重复的元素。
例如,给出
中序遍历 inorder = [9,3,15,20,7]
后序遍历 postorder = [9,15,7,20,3]
复制代码
返回如下的二叉树:
3
/ \
9 20
/ \
15 7
复制代码
解析
递归法
- 步骤:
- 1、判断数组大小是否为0,为0则表示空节点
- 2、不为空,取后序遍历数组的最后一个元素(作为根节点)
- 3、在中序遍历中找到后序遍历的最后一个元素
- 4、切割中序数组,将中序数组分为中序左数组,中序右数组
- 5、切割后序数组,得到后序左数组,后序右数组
- 6、递归处理左区间和右区间
代码
class Solution
{
public:
TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder)
{
return traversal(inorder, postorder);
}
private:
TreeNode *traversal(vector<int> &inorder, vector<int> &postorder)
{
// 1、判断数组大小是否为0,为0则表示空节点,直接返回空
if (inorder.size() == 0)
{
return NULL;
}
// 取后序遍历的最后一个元素作为根节点
int rootVal = postorder[postorder.size() - 1];
// 设置根节点
TreeNode *root = new TreeNode(rootVal);
int splitPos;
// 3、查找中序遍历的分割点
for (splitPos = 0; splitPos < inorder.size(); splitPos++)
{
if (inorder[splitPos] == rootVal)
{
break;
}
}
// 4、切割中序数组,分为左数组和右数组
vector<int> inLeft(inorder.begin(), inorder.begin() + splitPos);
vector<int> inRight(inorder.begin() + splitPos + 1, inorder.end());
// 5、切割后序数组
// 首先舍去最后一个元素
postorder.resize(postorder.size() - 1);
// 后序数组的切割根据已有条件来获得
// 后序左数组的大小与中序左数组的大小相同,以此来找到切割点
vector<int> postLeft(postorder.begin(), postorder.begin() + inLeft.size());
vector<int> postRight(postorder.begin() + inLeft.size(), postorder.end());
// 6、递归处理左区间和右区间
root->left = traversal(inLeft, postLeft);
root->right = traversal(inRight, postRight);
return root;
}
};
复制代码