算法刷题笔记-重建二叉树

275 阅读2分钟

参考:B站UP--子烁爱学习(推荐大家观看原视频)

  • 题目描述:

  • 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

  • 例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。

  • 题目解析

    • 如果是以下的二叉树

    • 前序是1 2 4 5 3 6 7

    • 中序是4 2 5 1 6 3 7


    • 首先分析,前序遍历第一个数字就是根节点,这时候你去中序遍历中找到该数字,那么依据中序遍历原则,在这个数字左边的就是该树的左子树,在这个数字右边的就是该树的右子树

    • 这时候将左子树的前序和中序遍历拿出,当成一个独立的树,将右子树的前序和中序遍历拿出,当成另一个独立的树然后就重复上面的分析,递归分析直到拿出来的独立的树的左节点是一个叶子节点,右节点也是一个叶子节点,终止递归。成功构建二叉树

    • 依据当前例子的分析,左子树:前序[2 4 5],中序[4 2 5],则可以推出,左子树的根节点是2,左叶子节点4,右叶子节点是5

    • 右子树:前序[3 6 7],中序[6 3 7],则可以推出,左子树的根节点是3,左叶子节点6,右叶子节点是7

  • 代码展示

public TreeNode reConstructBinaryTree(int [] pre,int [] in){
        return find(pre,in,0,pre.length-1,0,in.length-1);
    }


    //1 [2 4 7] [3 5 6 8]
    //[4 7 2] 1 [5 3 8 6]
	//left和right用于确定左子树和右子树的前序遍历的范围和长度大小,这个例子里就是3和4
	//leftin和rightin用于确定左子树和右子树的中序遍历的范围大小,这个例子里就是3和4
    public TreeNode find(int[] pre,int[] in,int left,int right,int leftin,int rightin){
        //判定left如果大于等于数组长度,就已经遍历到了最右边,这个位置也就是最多左右重合,定义确定的范           围就是1,就是一个节点的数字
        if(left>=pre.length || leftin>=in.length || left>right || leftin>rightin){
            return null;
        }
        //确定根节点
        int value = pre[left];
        TreeNode treeNode = new TreeNode(value);
        int count=leftin;
        //确定左子树的遍历长度
        while(in[count] != value){
            count++;
        }
        count-=leftin;
		//确定左子树、右子树前序和中序,递归出完整的子树结构
        treeNode.left=find(pre, in, left+1, left+count, leftin, leftin+count-1);
        treeNode.right=find(pre,in,left+count+1,right,leftin+count+1,rightin);
        return treeNode;
    }