题目
题意
给出一颗二叉树的两种 d f s dfs dfs 序列,即同一层上没有明确的左右子树概念,两种序列可以以根节点-左/右子树-另一颗子树的顺序实现。求一颗满足两种 d f s dfs dfs 序列的二叉树,输出每一个节点的父亲节点。题目保证有解
思路
因为是一颗树的重构,我们可以同时从两棵树的
d
f
s
dfs
dfs 序列入手,我们可以分别在两个序列上,找到当前子树所在的区间,并且可以通过判断当前位在两个序列中的值是否相同,来判断当前父亲节点需要两棵子树还是一棵子树。
原因是这样的,因为两个
d
f
s
dfs
dfs 序列,是以这样的形势展现的:
r
o
o
t
−
l
s
root - ls
root−ls _
r
o
o
t
−
l
s
−
r
s
root - ls - rs
root−ls−rs _
r
o
o
t
−
r
s
root - rs
root−rs
r
o
o
t
−
r
s
root - rs
root−rs _
r
o
o
t
−
r
s
−
l
s
root - rs - ls
root−rs−ls _
r
o
o
t
−
l
s
root - ls
root−ls
或
r
o
o
t
−
l
s
root - ls
root−ls _
r
o
o
t
−
l
s
−
r
s
root - ls - rs
root−ls−rs _
r
o
o
t
−
r
s
root - rs
root−rs
r
o
o
t
−
l
s
root - ls
root−ls _
r
o
o
t
−
l
s
−
r
s
root - ls - rs
root−ls−rs _
r
o
o
t
−
r
s
root - rs
root−rs
那么当我们确定一个根后,如果他们的后一个节点是相同的,我们可以判断后一个节点引导了一个连在当前根的子树。如果当前根的后一个值在两个序列中是不同的,那么这两个值各自引导了一个连在当前根的子树。儿通过查找两个值的两个序列中的位置,我们可以确定子树所在的序列,然后递归调用。
需要注意的一点是,因为我们的树是二叉的,所以当前根有两棵子树时,是不用考虑的,因为子树长度是确定的,而如果当前根只有一棵子树的话,我们需要判断是否存在另一颗子树。
代码
递归调用实现
const int maxn = 1e5+5;
int a[maxn], b[maxn], pa[maxn], pb[maxn];
int pre[maxn];
void build(int root, int la, int lb, int &len){
if(len == 0) return;
if(a[la] != b[lb]){
pre[a[la]] = root;
pre[b[lb]] = root; // la-ls, lb-rs;
int ls_la = la+1, ls_ra = pa[b[lb]]-1;
int ls_len = ls_ra - ls_la + 1;
int rs_lb = lb+1, rs_rb = pb[a[la]]-1;
int rs_len = rs_rb - rs_lb + 1;
int ls_lb = pb[a[la]]+1;
int rs_la = pa[b[lb]]+1;
build(a[la], ls_la, ls_lb, ls_len); // ls
build(b[lb], rs_la, rs_lb, rs_len); // rs
len = ls_len + rs_len + 2;
return ;
}
else {
pre[a[la]] = root;
int ls_la = la+1, ls_lb = lb+1, ls_len = len-1;
build(a[la], ls_la, ls_lb, ls_len);
if(ls_len+1 < len){
int rs_root = a[la+ls_len+1], rs_la = la+ls_len+2, rs_lb = lb+ls_len+2;
int rs_len = len - ls_len - 2;
pre[rs_root] = root;
build(rs_root, rs_la, rs_lb, rs_len);
len = ls_len + rs_len + 2;
}
}
}
int main()
{
int T, n;
sd(T);
while(T--){
sd(n);
rep(i, 0, n) {
sd(a[i]);
pa[a[i]] = i;
}
rep(i, 0, n) {
sd(b[i]);
pb[b[i]] = i;
}
build(0, 0, 0, n);
rep(i, 1, n+1){
printf("%d%c", pre[i], i==n?'\n':' ');
}
}
return 0;
}