题目描述
AC代码
题意很简单,就是根据前序序列和中序序列构造二叉树,根据前序遍历的特点,我们可以知道preorder的第一个元素是根节点,那么根据中序遍历得到的中序序列中,只要知道了根结点(父节点)是谁,那么我们就可以分清楚左右子树是谁,从而知道父节点的左右儿子分别是谁,以此来构建一颗二叉树。
下面的做法是通过递归来完成构造的,我们用哈希表来存储数组下标和中序序列的关系。递归时,从先序遍历的数组中找到父节点,计算中序遍历的数组中父节点之前的元素个数k(就是左边有多少个儿子/孙子/…),然后根据这个k写左右子树的递归方法签名就行了。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
HashMap<Integer,Integer> map=new HashMap<>();
public TreeNode buildTree(int[] preorder, int[] inorder) {
int len=preorder.length;
for(int i=0;i<len;i++){
map.put(inorder[i],i);
}
return dfs(preorder,inorder,0,len-1,0,len-1);
}
TreeNode dfs(int pre[],int in[],int pl,int pr,int il,int ir){
if(il>ir)
return null;
int k=map.get(pre[pl])-il;
TreeNode root=new TreeNode(pre[pl]);
root.left=dfs(pre,in,pl+1,pl+k,il,il+k-1);
root.right=dfs(pre,in,pl+k+1,pr,il+k+1,ir);
return root;
}
}
其中,k=map.get(pre[pl])-il
是求出在中序遍历的数组当中,根节点的左侧元素个数;root.left=dfs(pre,in,pl+1,pl+k,il,il+k-1);
,因为求根节点(父节点)的时候用掉了pre数组下标为pl的元素,所以求root.left从pl+1开始,一直到pl+k结束(因为根节点左侧有k个元素),中序遍历则是从il到il+k-1,因为il+k是根节点(父节点),所以在求root.right时,中序遍历的左遍历起点为il+k+1。