题目:求解最近公共祖先
思路:分别从两个结点向上遍历,最先遍历两次的就是LCA
涉及:根据中序和先序序列确定二叉树,我使用了map来映射结点value和下标的关系
易错点:
1.节点不存在,要输出不存在的结点,并结束
2.若其中一个结点是另一个结点的情况 ;和两个结点互不为祖先的情况,一定有共同祖先,因为有根嘛。
#include<iostream>
#include<string.h>
#include<map>
#define MAXN 10005
using namespace std;
map<int,int> value_index;
int vis[MAXN];
struct Node{
int value;
int left=-1,right=-1,parent=-1;//下标
};
struct Node node[MAXN];
int inOrder[MAXN],preOrder[MAXN];
int ind=0;
int createTree(int left_in,int right_in,int left_pre,int right_pre){//返回下标
if(left_in>right_in)return -1;
int root=preOrder[left_pre];
int root_pos_in=left_in;//中序序列根的下标
while(inOrder[root_pos_in]!=root){
root_pos_in++;
}
int i = ind++;
value_index[root]=i;//
node[i].value=root;
node[i].left=createTree(left_in,root_pos_in-1, left_pre+1,left_pre+root_pos_in-left_in-1);
if(node[i].left!=-1){
node[node[i].left].parent=i;
}
node[i].right=createTree(root_pos_in+1,right_in, left_pre+root_pos_in-left_in+1, right_pre);
if(node[i].right!=-1){
node[node[i].right].parent=i;
}
return i;
}
int getLCA(int a,int b){//传入的是结点值,返回下标
memset(vis,0,sizeof(vis));
a=value_index[a];//下标
b=value_index[b];
while(a!=-1){
vis[a]++;
a=node[a].parent;
}
while(b!=-1){
vis[b]++;
if(vis[b]>1)return b;
b=node[b].parent;
}
return -1;
}
int main(){
int m,n;//m测试的节点对,n结点个数
cin>>m>>n;
for(int i=0;i<n;i++){
cin>>inOrder[i];
}
for(int i=0;i<n;i++){
cin>>preOrder[i];
}
//确定二叉树
int root_i=createTree(0,n-1,0,n-1);
//求解最近共同祖先 结点a,b。我的思路是:分别向上遍历,如果有那个结点最先被遍历两次就是最近共同祖先
for(int i=0;i<m;i++){
int a,b;
cin>>a>>b;
if(value_index.count(a)==0&&value_index.count(b)==0){
printf("ERROR: %d and %d are not found.\n",a,b);
continue;
}
else if(value_index.count(a)==0){
printf("ERROR: %d is not found.\n",a);continue;
}
else if(value_index.count(b)==0){
printf("ERROR: %d is not found.\n",b);continue;
}
int c=getLCA(a,b);
c=node[c].value;
if(vis[value_index[a]]>1){
printf("%d is an ancestor of %d.\n",a,b);
}
else if(vis[value_index[b]]>1){
printf("%d is an ancestor of %d.\n",b,a);
}
else {
// printf("%d %d %d\n",vis[value_index[a]],vis[value_index[b]],vis[value_index[c]]);
printf("LCA of %d and %d is %d.\n",a,b,c);
}
}
}