牛客刷题——重建二叉树

题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。

eg: 输入:[1,2,3,4,5,6,7],[3,2,4,1,6,5,7]

输出:{1,2,5,3,4,6,7}

真不敢相信我写出来了。。。二叉树重建在之前数据结构的课上就学过,通过先序遍历和中序遍历能够确定一棵二叉树,思路其实还挺简单的,根据先序遍历可以确定根节点,结合中序遍历确定左右子树,递归地进行判断。

以例题为例,对于先序遍历 1,2,3,4,5,6,7,可以确定根节点是1,在中序遍历中找到1,那么1的左边就是其左子树3,2,4,右边就是右子树6,5,7,然后根据左子树的长度3,可以在先序遍历中确定子树的先序遍历,从根节点的后面3个构成了左子树的先序2,3,4,后面的元素则是右子树的先序,5,6,7,并且对于先序遍历,第一个元素是根节点,因此可以直接确定1的左孩子是2,右孩子是5,构建出其父子关系,然后分别以左孩子为根节点,对左子树递归进行重建,以右孩子为根节点,对右孩子进行构建,直到每个区间只有一个节点,则直接返回,因为对于单个节点,已经在上一步进行处理了。

 完整代码如下:

public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
        if(pre.length==0) {
        	return null;
        }
        TreeNode root = new TreeNode(pre[0]);
        reConstruct(root, pre, in, 0, pre.length-1, 0, in.length-1);
        return root;
    }
    public static void reConstruct(TreeNode root,int[] pre,int[]in,int pb,int pe,int ib,int ie) {
    	if(pb>=pe) {
    		return ;
    	}
    	int r = pre[pb];
    	int index = find(in, r);  //index为root节点在中序遍历中位置,根据index划分左右子树
    	//中序左子树 [ib,index-1] 右子树[index+1,ie]
    	int len = index-ib; //左子树长度
    	//先序左子树 [pb+1,pb+len] 右子树[pb+len+1,pe]
    	if(pb+1<=pb+len) {//如果左孩子存在
    		TreeNode lchild = new TreeNode(pre[pb+1]);
        	root.left = lchild;	
    	}
    	if(pb+len+1<=pe) { //如果右孩子存在
    		TreeNode rchild = new TreeNode(pre[pb+len+1]);
        	root.right = rchild;
    	}
    	reConstruct(root.left, pre, in, pb+1, pb+len, ib, index-1);
    	reConstruct(root.right, pre, in, pb+len+1, pe, index+1, ie);
    }
    public static int find(int[] arr,int index) {
		for(int i=0;i<arr.length;i++) {
			if(arr[i]==index) {
				return i;
			}
		}
		return -1;
	}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值