树中两个结点 U 和 V 的最低公共祖先(LCA)是指同时具有 U 和 V 作为后代的最深结点。
给定二叉树中的任何两个结点,请你找到它们的 LCA。
输入格式
第一行包含两个整数 M 和 N,分别表示询问结点对数以及二叉树中的结点数量。
接下来两行,每行包含 N 个不同的整数,分别表示二叉树的中序和前序遍历。
保证二叉树可由给定遍历序列唯一确定。
接下来 M 行,每行包含两个整数 U 和 V,表示一组询问。
所有结点权值均在 int 范围内。
输出格式
对于每对给定的 U 和 V,输出一行结果。
如果 U 和 V 的 LCA 是 A,且 A 不是 U 或 V,则输出 LCA of U and V is A.。
如果 U 和 V 的 LCA 是 A,且 A 是 U 或 V 中的一个,则输出 X is an ancestor of Y.,其中 X 表示 A,Y 表示另一个结点。
如果 U 或 V 没有在二叉树中找到,则输出 ERROR: U is not found. 或 ERROR: V is not found. 或 ERROR: U and V are not found.。
数据范围
1≤M≤1000,
1≤N≤10000
输入样例:
6 8
7 2 3 4 6 5 1 8
5 3 7 2 6 4 8 1
2 6
8 1
7 9
12 -3
0 8
99 99
输出样例:
LCA of 2 and 6 is 3.
8 is an ancestor of 1.
ERROR: 9 is not found.
ERROR: 12 and -3 are not found.
ERROR: 0 is not found.
ERROR: 99 and 99 are not found.
又是一道LCA的题,但是这次的树并不是直接是二叉搜索树。
我们可以中序遍历每个节点,人为的给这每个节点添加一个数做标记,这样这棵树就具有了类似二叉搜索树的性质,而我们通过对添加的标记进行比较,就可以达到判断向左走还是向右走的目的。
#include <bits/stdc++.h>
using namespace std;
struct node
{
int data;
struct node*l,*r;
}a[10101];
int n,m,k;
unordered_map<int,int> mp;
unordered_map<int,int> path;
int pre[10100],inorder[10010];
int cnt=1;
struct node*create(int h1,int h2,int len)//前、中、长度
{
if(len==0)
return NULL;
struct node*p;
p = new node;
p->data = pre[h1];
int i = mp[pre[h1]];
int l1 = i-h2;
int l2 = len-1-l1;
p->l = create(h1+1,h2,l1);
p->r = create(h1+1+l1,i+1,l2);
return p;
}
void getid(struct node*root)
{
if(root)
{
getid(root->l);
path[root->data] = cnt++;
getid(root->r);
}
}
int main()
{
cin >>m >>n;
for(int i=1;i<=n;i++)
cin >>inorder[i],mp[inorder[i]] = i;
for(int i=1;i<=n;i++)
cin >>pre[i];
struct node*root = create(1,1,n);
getid(root);
for(int i=1;i<=m;i++)
{
int x,y;
cin >> x >>y;
if(!mp.count(x)&&!mp.count(y))
printf("ERROR: %d and %d are not found.\n",x,y);
else if(!mp.count(x))
printf("ERROR: %d is not found.\n",x);
else if(!mp.count(y))
printf("ERROR: %d is not found.\n",y);
else
{
struct node*p=root;
int xx = path[x];
int yy = path[y];
while((xx<path[p->data]&&yy<path[p->data])||(xx>path[p->data]&&yy>path[p->data]))
{
if(xx<path[p->data]&&yy<path[p->data])
p=p->l;
else if(xx>path[p->data]&&yy>path[p->data])
p=p->r;
}
if(p->data == x)
printf("%d is an ancestor of %d.\n",x,y);
else if(p->data == y)
printf("%d is an ancestor of %d.\n",y,x);
else
printf("LCA of %d and %d is %d.\n",x,y,p->data);
}
}
return 0;
}