从中序与后序遍历序列构造二叉树
题目链接:力扣题目链接
难度:中等
给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。
示例
输入:inorder = [9,3,15,20,7], postorder = [9,15,7,20,3]
输出:[3,9,20,null,null,15,7]
定义二叉树节点
//二叉树节点的定义。
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(){}
TreeNode(int val){
this.val = val;
}
TreeNode(int val,TreeNode left,TreeNode right){
this.val = val;
this.left = left;
this.right = right;
}
}
思路
1.利用后续找到根节点
2.在中序遍历中找到跟系欸但的位置root_index,则root_index左边是左子树中序的遍历,右边是右子树的中序遍历;假如i_left为中序遍历的左端点,i_right对应为中序遍历的右端点;p_left为后续遍历的左端点,p_right为后续遍历的右端点。
3.由上可知, 左子树的中序遍历的区间为 [i_left , root_index - 1]
右子树的中序遍历的区间为 [root_index + 1 , i_right]
4.左子树在中序遍历的长度为 [root_index - 1 - i_left + 1](加一是因为索引从零开始 长度加1)
后序与中序左子树的长度都是相等的所以得出:
左子树的后续遍历的区间为 [p_left , p_left + root_left - 1 - i_left]
右子树的后序遍历的区间为 [p_left + root_left - 1 - i_left + 1 , p_right - 1]
具体操作:
1.用HashMap记录每个值在中序遍历中的位置,键存储元素值,值存储元素的位置
2.利用后序遍历找最后一个元素值,也就是根节点值
3.确定左右子树的后序和中序递归创造出左右树加根
4.最后将根节点的左右指针指向两棵树
递归代码
class Solution{
//使用HashMap记录每个值在中序遍历中的位置
private Map<Integer,Integer> infix = new HashMap<>();
public TreeNode buildTree(int[] inorder,int[] postorder){
int len = inorder.length;
for (int i=0;i<len;i++){
infix.put(inorder[i],i);
}
return build(inorder,postorder,0,len-1,0,len-1);
}
private TreeNode build(int[] inorder,int[] postorder,int i_left,int i_right,int p_left,int p_right){
if (p_left > p_right){
return null;
}
int root_index = infix.get(postorder[p_right]);
TreeNode root = new TreeNode(postorder[p_right]);
root.left = build(inorder,postorder,i_left,root_index-1,p_left,p_left + root_index - 1 - i_left);
root.right = build(inorder,postorder,root_index + 1,i_right,p_left + root_index - 1 - i_left + 1,p_right - 1);
return root;
}
}