《剑指offer》面试题6:重建二叉树

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

思路:在二叉树的前序遍历序列中,第一个数字总是树的根节点的值。但在中序遍历序列中,根节点的值在序列的中间,左子树的节点的值位于根节点的值的左边,而右子树的节点的值位于根节点的值的右边。

辅助函数:判断异常情况,例如序列为空,不等长等。

功能函数:构建二叉树。

  1. pre的pres的节点记为root节点,在in中找到root节点的位置,根据root在in的片段中所处的位置,判断是否有左子树或者右子树。
  2. 如果存在子树,以左子树为例。根据左子树的长度,在pre中分割出左子树的片段,将片段中第一个值设置为root,进行新一轮的递归。
  3. 递归结束:没有左子树或者右子树。

难点:存在子树时,切割片段中pres,ins,pree,ine的设定。

 

Java题解

// 筛选空数列,数列不等长等异常情况
public TreeNode constructTree(int[] pre, int[] in) {
	if (pre.length==0 || in.length==0 || pre.length!=in.length)
		return null;
	return helpconstructTree(pre, in, 0, pre.length-1, 0, in.length-1);
}
// 构建二叉树主函数
public TreeNode helpconstructTree(int[] pre, int[] in, int pres, int pree, int ins, int ine) {
	TreeNode root = new TreeNode(pre[pres]);
	int rootloc = findRoot(in, pre[pres], ins, ine);
	if (rootloc > ins) {	// 有左子树
		int lpree = pres + (rootloc - ins);
		root.left = helpconstructTree(pre, in, pres+1, lpree, ins, rootloc-1);
	}
	if (rootloc < ine) {	// 有右子树
		int rpres = pres + (rootloc - ins) + 1;
		root.right = helpconstructTree(pre, in, rpres, pree, rootloc+1, ine);
	}
	return root;
}
// 找到pre第一个(root)在in的位置
public int findRoot(int[] nums, int num, int s, int e) {
	int i = s;
	for (; i <= e; i++) {
		if (nums[i] == num)
			return i;
	}
	return -1;
}

Python题解

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def buildTree(self, preorder, inorder):
        """
        :type preorder: List[int]
        :type inorder: List[int]
        :rtype: TreeNode
        """
        if len(preorder)==0 or len(inorder)==0:
            return None
        if len(preorder)==1 or len(inorder)==1:
            return TreeNode(preorder[0])
        
        for i in range(len(inorder)):
            if inorder[i] == preorder[0]:
                break
        root = TreeNode(preorder[0])
        root.left = self.buildTree(preorder[1:1+i], inorder[:1+i])
        root.right = self.buildTree(preorder[1+i:], inorder[1+i:])
        return root

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值