剑指Offer:重建二叉树

先贴代码
TreeNode类定义
class TreeNode{
    public int val;
    public TreeNode left;
    public TreeNode right;
    public TreeNode(int val){
        this.val=val;
    }
}

//不得不吐槽一下:以int[]作为参数大大增加了老夫的代码量

public static TreeNode reConstructBinaryTree(int[] pre, int[] in){
    int fatherData= pre[0];
    List<Integer> preList=new ArrayList<>();
    List<Integer> inList=new ArrayList<>();
    for(int i=0;i<pre.length;i++){
        preList.add(pre[i]);
        inList.add(in[i]);
    }
    int index= inList.indexOf(fatherData);
    TreeNode father=new TreeNode(fatherData);

    List<Integer> lInorder= inList.subList(0,index);
    List<Integer> rInorder= inList.subList(index+1, inList.size());
    List<Integer> rPreorder= preList.subList(index+1, preList.size());
    List<Integer> lPreorder= preList.subList(1,index+1);

    if(lInorder.size()!=0){
        father.left=reConstructBinaryTree(lPreorder.stream().mapToInt(Integer::intValue).toArray(),lInorder.stream().mapToInt(Integer::intValue).toArray());
    }
    if(rInorder.size()!=0){
        father.right=reConstructBinaryTree(rPreorder.stream().mapToInt(Integer::intValue).toArray(),rInorder.stream().mapToInt(Integer::intValue).toArray());
    }
    return father;
}

================================================================================================

思路:

以题目给出的序列为例:

前序:{1,2,4,7,3,5,6,8}           中序:{4,7,2,1,5,3,8,6}

本题目主要是根据回溯的思想解题:

由前序遍历的特点可知:

                                    节点1作为前序遍历的第一个节点,必然是根节点

由中序遍历的特点可知:

                                     节点1左边的{4,7,2}节点必然是在节点1的左子树上,{5,3,8,6}在其右子树上

接下来,在中序序列中根据1的位置进行左右切割,可以得出其左右子树的前序序列和中序列。

同理,对于前序{2,4,7}中序{4,7,2}的子树来说,节点2是根节点,{4,7}节点依据在中序序列中的位置:

                                      {4,7}在节点2的左子树上

依着这个思路递归下去,在每一个被切割出来的子序列中,选定其所代表的子树的根节点,然后使用上一级根节点的左/右指针指向新的根节点,就可以重新构建出原来的二叉树。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值