利用:
1.二叉排序树的性质:中序序列是一个升序序列;
2.二叉树的性质:中序序列中, 某项左边的关键字都在他的左子树, 右侧的都在右子树;
顺序遍历给定先序序列,若存在某关键字, 值大于等于n1、n2的小者(小者在该关键字左子树),小于n1、n2的大者(大者在其右子树),可以证明,该元素是n1、n2的最近ancestry;
其他方案:后序遍历, 访问栈中的元素都是当前元素的祖先, 保存两个元素的后序遍历栈, 找出最后面的相同值;(沃日后天考试, 不写了溜了溜了)
#include <cstdio>
#include <vector>
#include <algorithm>
#include <unordered_map>
using namespace std;
int main()
{
int M, N;
unordered_map<int, bool> inTree;
scanf("%d %d", &M, &N);
vector<int> pre(N);
for( int i = 0; i < N; ++i )
{
scanf("%d", &pre[i]);
inTree[ pre[i] ] = true;
}
for( int i = 0, n1, n2; i < M; ++i )
{
scanf("%d %d", &n1, &n2);
if( !inTree[n1] && !inTree[n2] )
printf("ERROR: %d and %d are not found.\n", n1, n2);
else if( !inTree[n1] || !inTree[n2] )
printf("ERROR: %d is not found.\n", inTree[n1] ? n2:n1);
else
for( int j = 0; j < N; ++j )
{
if( pre[j] <= max(n1, n2) && pre[j] >= min( n1, n2 ) )
{
if( pre[j] != n1 && pre[j] != n2 )
printf("LCA of %d and %d is %d.\n", n1, n2, pre[j]);
else printf("%d is an ancestor of %d.\n", pre[j], pre[j] == n1 ? n2:n1);
break;
}
}
}
}