- 题目:根据后序和中序遍历结果构建二叉树
- 难度:Medium
- 思路:递归(一开始我没理清递归函数的结构)具体思路在下面的代码里有写
- 代码:
/**
* 根据中序和后续遍历结果来建构二叉树
* @param inorder
* @param postorder
* @return
*/
public TreeNode buildTree(int[] inorder, int[] postorder) {
int inLen = inorder.length;
int postLen = postorder.length;
if(inLen == 0 || postLen == 0 || inLen != postLen){
return null;
}
HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();
for(int i = 0; i < inLen; i++){
map.put(inorder[i],i);
}
return recursion(inorder,0,inLen-1,postorder,0,postLen-1,map);
}
/**
*很容易看出这颗二叉树的构建是一个递归过程,所以需要找出递归的规律
*后续遍历结构从后往前分别作为根节点或者子树的根节点,
* 根据postorder的值找到相应的值在inorder里的index,这个index将是一个根节点,左右元素分别是左右子树,对于左右子树同样也是先找出根节点的在inorder中的index,将子树又分成两个子树
* 所以我们需要找到index,并且将左右子树的元素在postorder或者inorder里的起始结束位置确定,这样就可以递归建树了
* 对于找到每颗子树的根节点下标,需要借助一个HashMap,预先将中序的元素和下标分别作为key和value保存,然后在递归的过程可以通过postorder的元素到Map里进行下标查找
*
* @param inorder 中序遍历结果
* @param is 子树包含的元素在inorder里的起始位置
* @param ie 子树包含的元素在inorder里的结束位置(通过is和ie可以确定这颗子树所包含的所有元素)
* @param postorder 后续遍历结果
* @param ps 树包含的元素在postorder里的结束位置
* @param pe 树包含的元素在postorder里的结束位置(通过ps和pe可以确定这颗子树所包含的所有元素)
* @param map 存储中序遍历结果和对应下标
* @return
*/
private TreeNode recursion(int[] inorder, int is, int ie,int[] postorder, int ps, int pe,HashMap<Integer,Integer> map){
if(is > ie || ps > pe){
return null;
}
int ri = map.get(postorder[pe]);
TreeNode root = new TreeNode(postorder[pe]);
root.right = recursion(inorder, ri+1,ie,postorder,ri-is+ps,pe-1,map);
root.left = recursion(inorder,is,ri-1,postorder,ps,ri-is+ps-1,map);
return root;
}
- 根据前序和中序遍历结果构建二叉树,思路同上,需要主要下一次递归的preorder的起始位置
private TreeNode recursion(int[] preorder, int ps, int pe, int[] inorder, int is, int ie, HashMap<Integer,Integer> map){
if(ps > pe || is > ie){
return null;
}
TreeNode root = new TreeNode(preorder[ps]);
int ri = map.get(preorder[ps]);
root.right = recursion(preorder,ri-is+ps+1,pe,inorder,ri+1,ie,map);
root.left = recursion(preorder,ps+1,ri-is+ps,inorder,is,ri-1,map);
return root;
}