题目描述:
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。
假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
题目思路:
借用牛客网某大神的思路:
思路:利用递归依次判断每个节点的左子树和右子树,若可以延伸,则继续递归,若不可以延伸,则将其孩子节点设置为null。
分析:举个例子来说:
int[] pre = {1,2,4,7,3,5,6,8}//前序遍历
int[] in = {4,7,2,1,5,3,8,6}//中序遍历
1. pre的第一个节点“1”为根节点,在in中的位置下标为3,则可以判断in中{4,7,2},{5,3,8,6}分别为节点“1”的左子树与右子树的中序遍历。然后在pre中从“2”开始数,前3个数{2,4,7},后4个数{3,5,6,8}分别为节点“1”的左子树与右子树的前序遍历。
2. 接下来,再判断节点“1”的左右子树的子树。
以“1”的左子树pre{2,4,7},in{4,7,2}为例,pre的第一个节点“2”当前子树的根节点,{4,7}为节点“2”的左子树中序遍历也是前序遍历。
3. 依此判断,最终将所有的叶子结点找出。
代码:
/**
* 重建二叉树
* @author HeMing
*
*/
public class ReConstructBinaryTree {
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
TreeNode root = reConstructBinaryTree(pre, in, 0, pre.length-1, 0, in.length-1);
return root;
}
public TreeNode reConstructBinaryTree(int[] pre, int[] in,
int preStart, int preEnd,
int inStart, int inEnd){
if (preStart>preEnd||inStart>inEnd){
return null;
}
TreeNode root = new TreeNode(pre[preStart]);
for (int i = inStart; i <= inEnd; i++){
if (pre[preStart]==in[i]){
root.left = reConstructBinaryTree(pre,in,preStart+1,i-inStart+preStart,inStart,i-1);
root.right = reConstructBinaryTree(pre,in,i-inStart+preStart+1,preEnd,i+1,inEnd);
}
}
return root;
}
总结:
递归大法好,但是理解特别抽象,要多练习这样的思路。