题目
根据一棵树的前序遍历与中序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。
例如,给出
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]链接
思路
分治: 树可递归定义。
前序遍历为:
根
—左子树
—右子树
中序遍历为:左子树
—根
—右子树
由于前序遍历的第一个节点为根节点,所以可在中序遍历中找出这个根节点(因为节点不重复)下标idx
,找出之后,可由中序遍历确定这个根节点的左子树的节点个数 idx减去中序数组左边界,设为len
所以前序遍历数组继续划分为
前序遍历数组划分为左子树前序遍历
preorder[start+1,start+len]
,
中序遍历数组划分为左子树中序遍历inorder[start,idx-1]
右子树类似,只不过划分数组为
preorder[start+len+1,end]
,inorder[idx+1,end]
为下层递归使用。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
//用map存储下标映射,方便查找
Map<Integer,Integer>map=new HashMap<>();
public TreeNode buildTree(int[] preorder, int[] inorder) {
for(int i=0;i<inorder.length;i++){
map.put(inorder[i],i);
}
int len=preorder.length;
return helper(preorder,0,len-1,inorder,0,len-1);
}
/*
ps:preorder start
pe:preorder end
is:inorder start
in:inorder end
*/
TreeNode helper(int[]pre,int ps,int pe,int[]in,int is,int ie){
if (ps > pe) {
return null;
}
//创建根节点
TreeNode root=new TreeNode(pre[ps]);
//定位中序中的根节点
int root_inorder=map.get(pre[ps]);
//确定左子树节点个数
int left_len=root_inorder-is;
//即从[ps+1,ps+left_len],[is,root_inorder-1]全是左子树节点,剩余全为右子树节点
root.left=helper(pre,ps+1,ps+left_len,in,is,root_inorder-1);
//跳过当前根节点的所有左子树节点,来到右子树节点
root.right=helper(pre,ps+1+left_len,pe,in,root_inorder+1,ie);
return root;
}
}