重建二叉树
题目描述:
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
思路分析:
- 在二叉树的前序遍历中,第一个数字总是树的根节点;
- 从前序遍历中得到根节点的值,再在中序遍历序列中可遍历查到根节点的位置;
- 在中序遍历序列中,根节点左边的值为其左子树的中序遍历,记节点数为L,右边的值为其右子树的中序遍历,记节点数为R;
- 则在前序遍历中,第2~L+1个节点为左子树的前序遍历,剩下的节点为右子树的前序遍历;
- 得到左右子树的前序遍历和中序遍历后,便可以重建相应的子树;
- 结合上述分析,可通过递归的方式来重建一棵二叉树。
代码实现:
/**
* Definition for binary tree
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
if(pre == null||in == null) return null;
TreeNode root = constructSubTree(pre, 0, pre.length-1, in, 0, in.length-1);
return root;
}
public TreeNode constructSubTree(int[] pre , int startPreOrder , int endPreOrder ,int[] in , int startInOrder , int endInOrder){
TreeNode root = new TreeNode(pre[startPreOrder]);//前序遍历的第一个元素为根节点
int rootInOrder = startInOrder;
while(in[rootInOrder] != pre[startPreOrder]){
rootInOrder++;
}
int lSIO = startInOrder;//中序遍历的左子树开始处
int lEIO = rootInOrder-1;//中序遍历的左子树结束处
int lSPO = startPreOrder +1;//前序遍历的左子树开始处
int lEPO = lEIO-lSIO+lSPO;//前序遍历的左子树结束处
if(lSIO<=lEIO){
root.left = constructSubTree(pre, lSPO, lEPO, in, lSIO, lEIO);
}
int rSIO = rootInOrder+1;//中序遍历的右子树开始处
int rEIO = endInOrder;//中序遍历的右子树结束处
int rSPO = lEPO +1;//前序遍历的右子树开始处
int rEPO = endPreOrder;//前序遍历的右子树结束处
if(rSIO<=rEIO){
root.right = constructSubTree(pre, rSPO, rEPO, in, rSIO, rEIO);
}
return root;
}
}