一、根据前序和后序重建二叉树
输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。LeetCode面试题07
例如,给出:
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:
【法一】:推荐方法
public class Solution {
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
return dfs(pre,0,pre.length-1,in,0,in.length-1);
}
public TreeNode dfs(int [] pre,int preleft,int preright,int [] in,int inleft,int inright){
if(preleft > preright || inleft> inright) { //当到达边界条件时候返回null
return null;
}
//新建一个root
TreeNode root= new TreeNode(pre[preleft])
//对中序数组进行输入边界的遍历
for(int i = inleft; i<= inright; i++){
if(pre[preleft] == in[i]){ //找出中序数组中父结点位置i
//重构左子树,注意左子树的边界条件
root.left = dfs(pre,preleft+1,preleft+i-inleft,in,inleft,i-1);//i-inleft为左子树节点数
//重构右子树,注意右子树的边界条件
root.right = dfs(pre,preleft+i+1-inleft,preright,in,i+1,inright);
}
}
return pRootOfTree;
}
}
前序遍历左子树边界:preleft+1 —— preleft + i - inleft
; 中序遍历左子树边界:inleft —— i-1
左右子树以root的位置i为届,右子树在左子树的基础上加上:i - inleft
【法二】
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode buildTree(int[] preorder, int[] inorder) {
int preLen = preorder.length;
int inLen = inorder.length;
if(preLen == 0 && inLen == 0){
return null;
}
TreeNode root = new TreeNode(preorder[0]);
//找出中序遍历根节点下标
int preRootIndex = -1;
for(int i=0;i<inLen;i++){
if(inorder[i] == preorder[0]){
preRootIndex = i;
}
}
int[] inLeftTree = Arrays.copyOfRange(inorder,0,preRootIndex);
int[] inRightTree = Arrays.copyOfRange(inorder,preRootIndex+1,inLen);
int[] preLeftTree = Arrays.copyOfRange(preorder,1,inLeftTree.length+1);
int[] preRightTree = Arrays.copyOfRange(preorder,inLeftTree.length+1,preLen);
root.left = buildTree(preLeftTree,inLeftTree);
root.right = buildTree(preRightTree,inRightTree);
return root;
}
}
二、根据中序和后序重建二叉树
根据一棵树的中序遍历与后序遍历构造二叉树。
class Solution {
public TreeNode buildTree(int[] inorder, int[] postorder) {
return dfs(inorder,0,inorder.length-1,postorder,0,postorder.length-1);
}
public TreeNode dfs(int[] inorder,int inleft,int inright,int[] postorder,int postleft,int postright){
if(inleft > inright || postleft > postright){
return null;
}
TreeNode root = new TreeNode(postorder[postright]);//root
for(int i = inleft;i<=inright;i++){ //遍历中序数组
if(postorder[postright] == inorder[i]){//找出中序数组中父结点的位置i
//重构左子树
root.left = dfs(inorder,inleft,i-1,postorder,postleft,postleft+i-inleft-1);//左子树长i-inleft
//重构右子树
root.right = dfs(inorder,i+1,inright,postorder,postleft+i-inleft,postright-1);
}
}
return root;
}
}