给出一颗二叉树的后序遍历和中序遍历,你能计算出两个结点的最近公共祖先吗?
输入格式:
第一行给出两个整数N(N<=10000)和M(M<=10000),分别代表二叉树的结点数和我们接下来的询问数。
第二行和第三行分别给出N个整数,每个整数用空格分开,分别代表二叉树的后序遍历和中序遍历。
接下来M行,每行给出两个整数,代表我们要询问的两个结点的编号a和b。
输出格式:
对于每个我们要求的询问:
1.如果a和b中有一个或两个不在树上,输出"ERROR"。
2.否则在一行中输出一个整数,表示a和b的最近公共祖先。
输入样例:
在这里给出一组输入。例如:
3 3
2 3 1
2 1 3
1 2
2 3
0 3
输出样例:
在这里给出相应的输出。例如:
1
1
ERROR
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
很简单,看看就理解了
#include<bits/stdc++.h>
using namespace std;
int n,t;
int cheak(int post[],int mid[],int a,int b,int size)
{
int x=post[size-1];
int root;
// 找到中序的根节点;
for(root=0;root<size;root++) if(post[size-1]==mid[root]) break;
// 如果 a || b 等于当前的根节点,最近先祖就是此节点;
if(a==post[size-1]) return a;
if(b==post[size-1]) return b;
// 判断在两边还是 在同一边 ;
// 同一边 继续递归 ,两边 当前根节点输出
int p,q;
for(int i=0;i<n;i++)
{
if(a==mid[i]) p=i;
if(b==mid[i]) q=i;
}
if(p<root&&q<root) // 左
{
cheak(post,mid,a,b,root);
}
else if(p>root&&q>root) // 右
{
cheak(post+root,mid+root+1,a,b,size-root-1);
}
else return mid[root];
}
int main()
{
cin>>n>>t;
int post[10000],mid[10000];
for(int i=0;i<n;i++)
cin>>post[i];
for(int i=0;i<n;i++)
cin>>mid[i];
while(t--)
{
int a,b;
cin>>a>>b;
int flog=0;
for(int i=0;i<n;i++)
{
if(a==post[i])
{
flog++;break;
}
}
for(int i=0;i<n;i++)
{
if(b==post[i])
{
flog++;break;
}
}
if(flog<2)
{
printf("ERROR\n");continue;
}
int vv;
vv=cheak(post,mid,a,b,n);
printf("%d\n",vv);
}
}