PAT 甲级 1143 Lowest Common Ancestor (30 分)

自己真蠢,其实这题很简单,不需要建树,直接遍历preorder list就好了;

思路:

这是建树的笨方法:建树,先判断在不在树中,不在的话按要求输出;在的话按大小查找,找到的首个值介于需要查找的两个结点值之间的结点即lca;
自己真是蠢啊,用先根遍历序列去建树,然后去先根遍历找lca;
简单思路的就是之间在先根序列中找第一个值介于中间的点即lca;

代码:

#include<iostream>
#include<vector>
#include<unordered_map>
using namespace std;
vector<int> v;
unordered_map<int,pair<int,int>> mp;
void buildTree(int root,int begin,int end){
	mp[v[root]];
	if(end<begin) return;
	int right;
	for(right=begin;right<=end&&v[right]<v[root];right++);
	if(v[begin]<v[root]){
		mp[v[root]].first=v[begin];
		buildTree(begin,begin+1,right-1);
	}
	if(right<=end){
		mp[v[root]].second=v[right];
		buildTree(right,right+1,end);
	} 
}
int main(){
	int m,n;
	scanf("%d%d",&m,&n);
	v.resize(n);
	for(int i=0;i<n;i++) scanf("%d",&v[i]);
	buildTree(0,1,v.size()-1);
	for(int i=0;i<m;i++){
		int nd1,nd2;
		scanf("%d%d",&nd1,&nd2);
		bool find1=mp.find(nd1)!=mp.end(),find2=mp.find(nd2)!=mp.end();
		if(!find1||!find2)
			if(!find1&&!find2)
				printf("ERROR: %d and %d are not found.
",nd1,nd2);
			else
				printf("ERROR: %d is not found.
",!find1?nd1:nd2);
		else{
			int anc=v[0];
			while((anc-nd1)*(anc-nd2)>0) anc>nd1?anc=mp[anc].first:anc=mp[anc].second;
			if((anc-nd1)*(anc-nd2)==0) printf("%d is an ancestor of %d.
",anc==nd1?nd1:nd2,anc==nd1?nd2:nd1);
			else printf("LCA of %d and %d is %d.
",nd1,nd2,anc);
		}
	}
	return 0;
}
原文地址:https://www.cnblogs.com/yuhan-blog/p/12309084.html