问题:
根据一个树的先序序列和后序序列判断这棵树是否唯一。
首先,为什么会不唯一?
看上面两个图,它们的
先序序列:a b
后序序列:b a
是一样的,因为b既可以在左边也可以在右边 !
因此我们只需要判断根结点(递归意义上的“根”)下面有一个结点还是两个结点就可以了,如果只有一个结点,那么这棵树显然不唯一 !
如果根结点有两个子节点,那么左子节点和右子节点根据先序序列显然是可以分清的(先左后右)
参考柳神代码理解后一次ac,思路和柳神的要反一下(故意的hh),但是原理是一样的。
#include<cstdio>
#include<vector>
using namespace std;
vector<int> pre,in,post;
int n,m;
bool unique = true;
void In(int preL,int preR,int postL,int postR){
if(preL>preR)
return;
if(preL==preR){
in.push_back(pre[preL]);
return;
}
int t = postL;
while(t<n&&post[t]!=pre[preL+1])t++;
if((postR-t)==1)
unique = false;
int numL = t-postL+1;
In(preL+1,preL+numL,postL,postL+numL-1);
in.push_back(pre[preL]);
In(preL+numL+1,preR,t+1,postR-1);
}
int main(){
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&m);
pre.push_back(m);
}
for(int i=0;i<n;i++){
scanf("%d",&m);
post.push_back(m);
}
In(0,n-1,0,n-1);
if(unique)
printf("Yes\n");
else
printf("No\n");
for(int i=0;i<in.size();i++){
if(i!=0)
printf(" ");
printf("%d",in[i]);
}
printf("\n");
}