这道题目仅仅建立一棵树是不够的.需要找到树中每个值对应的中序遍历的顺序下表.这样,每次把当前值的下表和给定的下表a与b的下表进行比较,得到不同的结果
主要思想就是建立索引.
给出代码:
#include <iostream>
#include<vector>
#include<cstdio>
#include<unordered_map>
struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
};
using namespace std;
int preorder[10005];
int inorder[10005];
unordered_map<int,int> pos;//找到每一个元素对应中序遍历的位置
TreeNode* constructTree(int beg1,int end1,int beg2,int end2){
if(beg1>end1){
return nullptr;
}
int val=preorder[beg1];
int index=beg2;
for (int i = beg2; i <=end2 ; ++i) {
if(inorder[i]==val){
index=i;
}
}
auto *root=new TreeNode();
root->val=val;
root->left=constructTree(beg1+1,index-beg2+beg1,beg2,index-1);
root->right=constructTree(index-beg2+beg1+1,end1,index+1,end2);
return root;
}
void findLCA(TreeNode* root,int a,int b){
if(root==nullptr){
return;
}
int posA=pos[a];
int posB=pos[b];
int val=root->val;
int posRoot=pos[val];
if((posRoot>posA&&posRoot<posB)||(posRoot<posA&&posRoot>posB)){
printf("LCA of %d and %d is %d.\n",a,b,val);
return;
}
if(posRoot==posA||posRoot==posB){
printf("%d is an ancestor of %d.\n",val,posRoot==posA?b:a);
return;
}
if(posRoot>max(posA,posB)){
findLCA(root->left,a,b);
return;
}
findLCA(root->right,a,b);
}
int main() {
int M,N;
cin>>M>>N;
for (int i = 1; i <=N ; ++i) {
cin>>inorder[i];
pos[inorder[i]]=i;//安排好位置,在找祖先时方便,找祖先就是看在中序遍历的位置
}
for (int i = 1; i <= N; ++i) {
cin>>preorder[i];
}
vector<pair<int,int>> vector1;
for (int i = 0; i < M; ++i) {
int a,b;
cin>>a>>b;
vector1.emplace_back(a,b);
}
TreeNode* root=constructTree(1,N,1,N);
for(auto pair:vector1){
int a=pair.first;
int b=pair.second;
if(pos[a]==0&&pos[b]==0){
printf("ERROR: %d and %d are not found.\n",a,b);
}else if(pos[a]==0||pos[b]==0){
printf("ERROR: %d is not found.\n",pos[a]==0?a:b);
} else{
// findLCA(1,a,b,1,N);
findLCA(root,a,b);
}
}
return 0;
}