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)
}
//根据先序和中序还原二叉树
最新推荐文章于 2023-08-07 14:57:42 发布