题目大意:给一个前序遍历的二叉搜索树,求两点的最近公共祖先。
二叉搜索树 左<根,根<=右,所以中序遍历一定是升序的。
1.老套路,先建树,然后再找最近公共祖先
2.不用建树,根据性质直接遍历一遍前序遍历,因为中序遍历是有序。(左根右)
建树的代码
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;
// 前序二叉搜索树,中序遍历就是从小到大排序后的结果
int n,m;
unordered_map<int,int>mp;
struct node
{
int v;
node *left,*right;
node(int x) : v(x),left(NULL),right(NULL){}
}*tr;
node *build(int preL,int preR,vector<int> &v) //二叉搜索树建树
{
if(preL > preR) return NULL;
node *t = new node(v[preL]);
int k = preL;
while(v[preL] >= v[k]) k ++; //找到第一个右
t -> left = build(preL + 1, k - 1,v);
t -> right = build(k,preR,v);
return t;
}
int lca(node *t,int a,int b)
{
int val = t -> v;
if(val > a && val > b) return lca(t ->left,a,b);
else if (val < a && val < b) return lca(t-> right,a,b);
else return val;
}
int main()
{
cin >> n >> m;
vector<int>v(m);
for(int i = 0; i < m; i ++)
{
cin >> v[i];
mp[v[i]] = 1;
}
tr = build(0,m - 1,v);
while( n --)
{
int a,b;
cin >> a >> b;
if(!mp.count(a) && mp.count(b)) printf("ERROR: %d is not found.\n",a);
else if(mp.count(a) && !mp.count(b)) printf("ERROR: %d is not found.\n",b);
else if (!mp.count(a) && !mp.count(b)) printf("ERROR: %d and %d are not found.\n",a,b);
else
{
int t = lca(tr,a,b);
if(t == a) printf("%d is an ancestor of %d.\n",a,b);
else if(t == b) printf("%d is an ancestor of %d.\n",b,a);
else printf("LCA of %d and %d is %d.\n",a,b,t);
}
}
return 0;
}
不用建树直接遍历
#include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_map>
using namespace std;
// 前序二叉搜索树,中序遍历就是从小到大排序后的结果
int n,m,a,b;
unordered_map<int,int>mp;
int main()
{
cin >> n >> m;
vector<int>v(m);
for(int i = 0; i < m; i ++)
{
cin >> v[i];mp[v[i]] = 1;
}
while( n --)
{
cin >> a >> b;
if(!mp.count(a) && mp.count(b)) printf("ERROR: %d is not found.\n",a);
else if(mp.count(a) && !mp.count(b)) printf("ERROR: %d is not found.\n",b);
else if (!mp.count(a) && !mp.count(b)) printf("ERROR: %d and %d are not found.\n",a,b);
else
{
for(int i = 0; i < m; i ++)
{
if(a < v[i] && v[i] < b || a > v[i] && v[i] > b)
{
printf("LCA of %d and %d is %d.\n",a,b,v[i]);
break;
}
else if(a == v[i])
{
printf("%d is an ancestor of %d.\n",a,b);break;
}
else if(b == v[i]){
printf("%d is an ancestor of %d.\n",b,a);break;
}
}
}
}
return 0;
}