1.题目描述
给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。
链接:https://leetcode.cn/problems/construct-binary-tree-from-inorder-and-postorder-traversal
示例1:
inorder = [9,3,15,20,7], postorder = [9,15,7,20,3]
输出:[3,9,20,null,null,15,7]
示例2:
输入:inorder = [-1], postorder = [-1]
输出:[-1]
2.题目分析和解答
2.1 递归
2.1.1递归思路
这道题与前面105. 从前序与中序遍历序列构造二叉树的解法基本一样,所以可以模拟上一题的递归实现来实现这道题的求解。这个过程对于下标变化的把握可以通过自己写一个序列来辅助分析,还是很容易理解的。
以下面的树的遍历结果为例,我们还是可以根据后序遍历的最后一个值确定根节点,然后再在中序遍历中根据这个根节点将中序序列划分为左右两部分,分别作为根节点的左子树和右子树的节点集群.根据这个思想我们就可以实现下面的递归过程。
2.1.2递归代码(O(N),O(N))
class Solution {
// 前序遍历中树的节点值与下标值的map映射
unordered_map<int,int> index;
public:
TreeNode* build(vector<int>& inorder,vector<int>& postorder,int inLeft,int inRight,int postLeft,int postRight){
// 遍历列表为空返回空树
if(inLeft>inRight){
return nullptr;
}
// 记录后序遍历中的树的根节点以及中序遍历中的树的根节点
int postRoot = postRight;
int inorderRoot = index[postorder[postRoot]];
// 构造一颗只有根节点的树
TreeNode* root = new TreeNode(postorder[postRoot]);
// 确定树的左子树的节点个数
int leftSize = inorderRoot - inLeft;
//构造左子树
root->left = build(inorder,postorder,inLeft,inorderRoot-1