题目描述
给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。
示例 1:
输入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
输出: [3,9,20,null,null,15,7]
示例 2:输入: preorder = [-1], inorder = [-1]
输出: [-1]提示:
1 <= preorder.length <= 3000
inorder.length == preorder.length
-3000 <= preorder[i], inorder[i] <= 3000
preorder 和 inorder 均 无重复 元素
inorder 均出现在 preorder
preorder 保证 为二叉树的前序遍历序列
inorder 保证 为二叉树的中序遍历序列
做题思路
本题重点考察的是如何根据给定的 前序中序的结果去还原二叉树
想要把本题做出来必须要有一定的数据结构的基础,尤其是对二叉树的三种遍历方式有所了解才可以
前序遍历: 根 左 右
中序遍历: 左 根 右
后序遍历: 左 右 根
知道了二叉树的三种遍历方式我们再来看题目,题目中给我们的是二叉树的前序和中序的遍历结果。
我来大概的说一下本题的实现思路;
我们已经知道了前序遍历的话每一次都是先遍历的 根结点
通过这个根节点我们就可以到题目中给出的中序遍历的数组里面去寻找这个根节点,找到了这个根节点之后我们就可以得知这颗二叉树左子树一共有多少个结点以及右子树有多少个结点了(也可以理解为左或右子树的长度了)
然后我们就可以通过递归来接着上一步的操作继续的去执行,直到把先序数组全部都遍历完成,就可以结束开始回调了
代码实现
/**
* Definition for a binary tree node.
* public 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;
* }
* }
*/
class Solution {
public TreeNode buildTree(int[] preorder, int[] inorder) {
return makeTree(preorder,0,preorder.length-1,inorder,0,inorder.length-1);
}
public TreeNode makeTree(int[] preorder,int i,int j,int[] inorder,int p,int q){
if(i>j)return null;
TreeNode root=new TreeNode(preorder[i]);
int k=0;
while(inorder[k]!=preorder[i])k++;
int leftLen=k-p;
TreeNode left=makeTree(preorder,i+1,i+leftLen,inorder,p,k-1);
TreeNode right=makeTree(preorder,i+leftLen+1,j,inorder,k+1,q);
root.left=left;
root.right=right;
return root;
}
}