PAT 甲级 1151 LCA in a Binary Tree (30 分)

PAT 甲级 1151 LCA in a Binary Tree


太惭愧了,这题暴力解的,玩不来各个大佬的lca算法。

思路:

1.将中根先根序列存储,然后用递归分治分别求出每个key的父结点,同时记录结点层次;
2.用全局变量存储中根先根序列,然后以下标范围来限定子树范围,我之前在每次递归时又定义两个vector来复制树的一个区间,以起到遍历子树的效果,结果后三个内存超了;
3.对于每两个要检测的key,若不在树里,按要求输出;若在树里,则层次低的那个结点沿父结点往上爬,爬到和层次高的那个结点同一层次,然后它们同时往上爬,直到它们的值相等,那个值就是他们的最近共同祖先结点;最后按找到的那个值是不是它们中的一个按要求进行输出;

代码:

#include<iostream>
#include<vector>
#include<unordered_map>
using namespace std;
unordered_map<int,pair<int,int>> vec;
unordered_map<int,int> loca;
vector<int> inOr,preOr;
void findFather(pair<int,int> in,pair<int,int> pre,int level)
{
	int root=loca[preOr[pre.first]];
	if(root!=in.first)
	{
		vec[preOr[pre.first+1]]=make_pair(preOr[pre.first],level);
		indFather(make_pair(in.first,root-1),make_pair(pre.first+1,root-in.first+pre.first),level+1);
	}
	if(root!=in.second)
	{
		vec[preOr[root-in.first+pre.first+1]]=make_pair(preOr[pre.first],level);
		findFather(make_pair(root+1,in.second),make_pair(root-in.first+pre.first+1,pre.second),level+1);
	}
}
int main()
{
	int m,n,u,v;
	scanf("%d%d",&m,&n);
	inOr.resize(n); preOr.resize(n);
	for(int i=0;i<n;i++)
	{
		scanf("%d",&inOr[i]);
		loca[inOr[i]]=i
	} 
	for(int i=0;i<n;i++) scanf("%d",&preOr[i]);
	vec[preOr[0]]=make_pair(preOr[0],0);
	findFather(make_pair(0,n-1),make_pair(0,n-1),1);
	for(int i=0;i<m;i++)
	{
		scanf("%d%d",&u,&v);
		if((vec[u].first==0||vec[v].first==0)&&(vec[u].first!=0||vec[v].first!=0))
			printf("ERROR: %d is not found.\n",vec[u].first==0?u:v);
		else if(vec[u].first==0&&vec[v].first==0)
			printf("ERROR: %d and %d are not found.\n",u,v);
		else
		{
			int fau=u,fav=v;
			while(vec[fau].second!=vec[fav].second)
				vec[fau].second>vec[fav].second?fau=vec[fau].first:fav=vec[fav].first;
			while(fau!=fav)
			{
				fau=vec[fau].first;
				fav=vec[fav].first;
			}
			if(fau==u||fav==v)
				printf("%d is an ancestor of %d.\n",fau==u?u:v,fau==u?v:u);
			else
				printf("LCA of %d and %d is %d.\n",u,v,fau);
		}
	}
	return 0;
}
posted @ 2019-08-10 14:13  YuhanのBlog  阅读(75)  评论(0编辑  收藏  举报