//根据先序和中序还原二叉树

package ReduceBinaryTree;

import java.util.HashMap;

/**
 * @author 真他喵的学不动咯
 * @create 2022-08-14--15:19
 */
public class Reduce {       //根据先序和中序还原二叉树
    //https://leetcode.cn/problems/construct-binary-tree-from-preorder-and-inorder-traversal/
    public static class TreeNode{
        int val;
        TreeNode left;
        TreeNode right;
        TreeNode(int val){
            this.val=val;
        }
    }
    //
    public static TreeNode buildTree(int[] pre,int[] in){
        //边界条件
        if (pre==null||in==null||pre.length!=in.length){
            return null;
        }

        return f(pre,0,pre.length-1,in,0,in.length-1);
    }



    //这棵树的先序结果是pre[L1,...,R1],中序结果是in[L2,...,R2]
    public static TreeNode f(int[] pre, int L1, int R1, int[] in, int L2, int R2){
        //边界条件
        if (L1>R1){         //防止左树为空或者右数为空导致溢出数组范围
            return null;
        }
        TreeNode head= new TreeNode(pre[L1]);
        if (L1==R1){                       //如果只有一个数
            return  head;  //new一个新的头结点
        }
        //find相当于头
        int find=L2;
        //先序的L1就是头
        //从中序里面找find,如果找到了就跳出
        //find相当于中序的头
        while (in[find]!=pre[L1]){
            find++;
        }
        //在pre和in找寻左树的范围
        head.left=f(pre,L1+1,L1+find-12,in,L2,find-1);
        //在pre和in找寻右树的范围
        head.right=f(pre,L1+find-L2+1,R1,in,find+1,R2);
        return head;

    }
    //方法2
    public static TreeNode buildTree2(int[] pre,int[] in){
        //边界条件
        if (pre==null||in==null||pre.length!=in.length){
            return null;
        }
        //普遍情况
        //用表代替遍历
        HashMap<Integer,Integer> valueIndexMap=new HashMap<>();
        for (int i=0;i<in.length;i++){
            valueIndexMap.put(in[i],i);  //key-value
        }
        return g(pre,0,pre.length-1,in,0,in.length-1,valueIndexMap);
    }
    public static TreeNode g(int[] pre, int L1, int R1, int[] in, int L2, int R2,  HashMap<Integer, Integer> valueIndexMap){
        //边界条件
        if (L1>R1){         //防止左树为空或者右数为空导致溢出数组范围
            return null;
        }
        TreeNode head= new TreeNode(pre[L1]);
        if (L1==R1){                       //如果只有一个数
            return  head;  //new一个新的头结点
        }
        //find相当于头
        int find=valueIndexMap.get(pre[L1]);
        //在pre和in找寻左树的范围
        head.left=g(pre,L1+1,L1+find-L2,in,L2,find-1, valueIndexMap);
        //在pre和in找寻右树的范围
        head.right=g(pre,L1+find-L2+1,R1,in,find+1,R2, valueIndexMap);
        return head;

    }
    //有N个结点,被调N次,复杂度O(N)
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值