题意:
给出一棵二叉搜索树的前序遍历,问结点u和v的共同最低祖先是谁,利用先序遍历特点。
二叉搜索树满足:
节点的左子树只包含键小于节点键的节点。
节点的键只包含节点的右键大于或等于子树的节点的键。
左子树和右子树也必须是二叉搜索树。
题解:
样例:
6 3 1 2 5 4 8 7
根据题目要求我们可以得到:
红字则是该数字在前序遍历中出现的顺序(从0开始)
我们可以从题目要求下手,在本题中,根的左子树总是小于根,右子树总是大于根
查询u和v的lca,如果一个x(x不与u和v重合)同时满足x>u,x<v,说明u在x的左边,v在x的右边,那说明x就是u和v的lca
同理。x<u,x>v也是
当然x和u或v重合时也是
代码:
#include<bits/stdc++.h>
using namespace std;
map<int,bool> mp;
int main(){
int m,n,u,v,a;
cin>>m>>n;
vector<int> pre(n);
for (int i=0;i<n;i++){
cin>>pre[i];
mp[pre[i]]=true;
}
for (int i=0;i<m;i++)
{
cin>>u>>v;
for (int j=0;j<n;j++)
{
a=pre[j];
if ((a>u&&a<v)||(a>v&&a<u)||(a==u)||(a==v))break;
}
if (mp[u]==false&&mp[v]==false)
printf("ERROR: %d and %d are not found.\n",u,v);
else if (mp[u] == false || mp[v] == false)
printf("ERROR: %d is not found.\n", mp[u] == false ? u : v);
else if (a == u || a == v)
printf("%d is an ancestor of %d.\n", a, a == u ? v : u);
else
printf("LCA of %d and %d is %d.\n", u, v, a);
}
return 0;
}