后序的最后一个元素是根,在中序中根据根的位置划分出该根的左右子树。
中序加后序能唯一确定一个二叉树。
二叉树可以用两个map来存,键是root,左map存(root,root的左子节点),右map存(root,root的右子节点)。
时间复杂度O(n)。
import java.util.*;
class Main{
static int N = 40;
static int back[] = new int[N];
static int mid[] = new int[N];
static Map<Integer,Integer> index = new HashMap<>(); //存一个节点对应中序的位置
static Map<Integer,Integer> lson = new HashMap<>(); //存一个节点的左儿子
static Map<Integer,Integer> rson = new HashMap<>(); //存一个节点的右节点
static int n;
public static void main(String[] arsg) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
for(int i = 1;i <= n;i++) {
back[i] = sc.nextInt();
}
for(int i = 1;i <= n;i++) {
mid[i] = sc.nextInt();
index.put(mid[i],i);
}
int root = build(1,n,1,n);
bfs(root);
}
static int build(int bl,int br,int ml,int mr) { //bl,br是后序子区间的左右端点,ml,mr是中序子区间的左右端点
int root = back[br];
int k = index.get(root);
if(ml < k) {
lson.put(root,build(bl,k-ml+bl-1,ml,k-1)); //画区间进行求解左区间长度length=k-1-ml=x-bl ==> x
}
if(mr > k) {
rson.put(root,build(k+br-mr,br-1,k+1,mr)); //有区间长度length=mr-(k+1)=br-1-x ==> x
}
return root;
}
static void bfs(int root) {
Queue<Integer> q = new LinkedList<>();
q.offer(root);
while(!q.isEmpty()) {
int x = q.poll();
System.out.print(x + " ");
if(lson.get(x) != null) {
q.offer(lson.get(x));
}
if(rson.get(x) != null) {
q.offer(rson.get(x));
}
}
}
}