105. 从前序与中序遍历序列构造二叉树
题目:从前序与中序遍历序列构造二叉树
首先需要了解前序和中序遍历的一些概念
拿题目中的例子来说,从先序的第一个开始构造,选择3,在中序找到3,3左边的就是节点3左子树的内容,3右边的是节点3右子树的内容,所以在中序中3左边的个数就是左子树的长度,在中序中3右边的个数就是右子树的长度,这里就需要用map记下值和索引的对应关系方便查(能用map是因为无重复元素)。显然,由于先序遍历是从左边开始的,所以计算出左子树的长度,当前的下标+长度,这之前的是左子树上的,之后的是右子树上的。
下面代码:
Map<Integer, Integer> map;
public TreeNode buildTree(int[] preorder, int[] inorder) {
map = new HashMap<>(inorder.length);
//记录中序遍历值和下标的对应关系
for (int i = 0; i < inorder.length; i++) {
map.put(inorder[i], i);
}
TreeNode res = build( 0, inorder.length - 1,0, preorder, inorder);
return res;
}
//有返回值,因为拼接树要用到
//方法体中的方法只在当前时刻有用,不是全局的
private TreeNode build( int leftPre, int rightPre,int leftIn, int[] preorder, int[] inorder) {
//在确定左子树之后,得到左子树的长度,超过界限的值说明没有子树了。
if(leftPre>rightPre){
return null;
}
//根节点的值
int rootVal = preorder[leftPre];
TreeNode root = new TreeNode(rootVal);
//当前节点在中序序列中的位置
int indexInOrder = map.get(rootVal);
//左子树的长度
int leftLen = indexInOrder-leftIn;
//leftPre:当前值在先序中的位置
//rightPre:当前值在先序中最大的位置
//leftIn:inorder中的左边界(用于确定长度)
//探索左子树的时候,从当前节点左边,先序中第一个开始找
root.left= build(leftPre+1, leftPre+leftLen, leftIn , preorder, inorder);
//探索右子树
root.right= build(leftPre+leftLen+1, rightPre, indexInOrder+1 , preorder, inorder);
return root;
}
106. 从中序与后序遍历序列构造二叉树
题目:106. 从中序与后序遍历序列构造二叉树
后序遍历的做法是:从最后一个开始,每次都作为根节点,但是先构造的是右子树。
其余几乎一模一样,这不过这里要设置的是右边界。
public TreeNode buildTree(int[] inorder, int[] postorder) {
Map<Integer, Integer> map = new HashMap<>(inorder.length);
for (int i = 0; i < inorder.length; i++) {
map.put(inorder[i], i);
}
TreeNode res = build2( 0, inorder.length - 1,inorder.length - 1, postorder, inorder, map);
return res;
}
private static TreeNode build2( int leftPre, int rightPre,int rightIn, int[] postorder, int[] inorder, Map<Integer, Integer> map) {
//在确定左子树之后,得到左子树的长度
if(leftPre>rightPre){
return null;
}
//根节点的值
int rootVal = postorder[rightPre];
TreeNode root = new TreeNode(rootVal);
//当前节点在中序序列中的位置
int indexInOrder = map.get(rootVal);
//右子树的长度
int rightLen = rightIn-indexInOrder;
//rightIn为啥是-1,因为是从右往左的
root.right= build2(rightPre-rightLen, rightPre-1, rightIn , postorder, inorder, map);
root.left= build2(leftPre, rightPre-rightLen-1, indexInOrder-1 , postorder, inorder, map);
return root;
}