1、题目描述
https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/
2、回顾二叉树的前序/中序/后序得到的序列特点
我们首先回顾三种遍历:
void traverse(TreeNode root) {
// 前序遍历
preorder.add(root.val);
traverse(root.left);
traverse(root.right);
}
void traverse(TreeNode root) {
traverse(root.left);
// 中序遍历
inorder.add(root.val);
traverse(root.right);
}
void traverse(TreeNode root) {
traverse(root.left);
traverse(root.right);
// 后序遍历
postorder.add(root.val);
}
对应得到了的数组序列特点:
基于以上的理解我们可以做:
class Solution {
public TreeNode buildTree(int[] preorder, int[] inorder) {
return build(preorder,0,preorder.length-1,inorder,0,inorder.length-1);
}
//preorder前序序列,inorder后序序列,preStart,preEnd,inStart,inEnd都是对应索引
public TreeNode build(int[]preorder,int preStart,int preEnd,int[]inorder,int inStart,int inEnd){
if(preStart>preEnd) return null;
//构建根节点,根节点是前序遍历的第一个节点
TreeNode root = new TreeNode(preorder[preStart]);
int root_index = 0;//1个元素
//寻找中序遍历的根节点索引,从而获得左子树的节点个数和右子树的节点个数
for(int i=inStart;i<=inEnd;i++){
if(inorder[i]==root.val){
root_index = i;
break;
}
}
int left_size = root_index-inStart;//左子树节点个数 root_index-inStart+1-1=root_index-inStart
//构建左子树
root.left = build(preorder,preStart+1,preStart+left_size,inorder,inStart,root_index-1);
//构建右子树
root.right = build(preorder,preStart+left_size+1,preEnd,inorder,root_index+1,inEnd);
return root;
}
}