已知二叉树的先序和中序遍历,求其最低的公共祖先结点。
本题和1143十分相似,不用建树,直接用map把树映射成二叉搜索树,之后按照1143同样的方法就容易解决了。
坑点如下
1,二叉搜索树的中序遍历一定是一个从小到大的数组,可以利用这一性质来进行映射。
#include<cstdio>
#include<map>
#include<vector>
using namespace std;
map<int,int>re,y;
int main(){
int m,n,v1,v2,u,v,j;
scanf("%d%d",&m,&n);
vector<int>in(n+1),pre(n+1),rpre(n+1);
for(int i=1;i<=n;i++)
scanf("%d",&in[i]);
for(int i=1;i<=n;i++)
scanf("%d",&pre[i]);
for(int i=1;i<=n;i++)
{ re[in[i]]=i;
y[i]=in[i];}
for(int i=1;i<=n;i++)
rpre[i]=re[pre[i]];
while(m--){
scanf("%d%d",&v1,&v2);
if(re.find(v1)==re.end()&&re.find(v2)==re.end()){
printf("ERROR: %d and %d are not found.\n",v1,v2);
continue;
}
if(re.find(v1)==re.end()||re.find(v2)==re.end()){
printf("ERROR: %d is not found.\n",re.find(v1)==re.end()?v1:v2);
continue;
}
else{u=re[v1],v=re[v2];
for(int i=1;i<=n;i++)
{ int j=rpre[i];
if((j>u&&j<v)||(j<u&&j>v))
{ printf("LCA of %d and %d is %d.\n",v1,v2,y[j]);
break;}
if(j==u||j==v)
{ printf("%d is an ancestor of %d.\n",y[j],j==u?v2:v1);
break;}
}
}
}
return 0;
}