PAT A1151 LCA in a Binary Tree (30 分)

The lowest common ancestor (LCA) of two nodes U and V in a tree is the deepest node that has both U and V as descendants.

Given any two nodes in a binary tree, you are supposed to find their LCA.

Input Specification:

Each input file contains one test case. For each case, the first line gives two positive integers: M (≤ 1,000), the number of pairs of nodes to be tested; and N (≤ 10,000), the number of keys in the binary tree, respectively. In each of the following two lines, N distinct integers are given as the inorder and preorder traversal sequences of the binary tree, respectively. It is guaranteed that the binary tree can be uniquely determined by the input sequences. Then M lines follow, each contains a pair of integer keys U and V. All the keys are in the range of int.

Output Specification:

For each given pair of U and V, print in a line LCA of U and V is A. if the LCA is found and A is the key. But if A is one of U and V, print X is an ancestor of Y. where X is A and Y is the other node. If U or V is not found in the binary tree, print in a line ERROR: U is not found. or ERROR: V is not found. or ERROR: U and V are not found..

Sample Input:

6 8
7 2 3 4 6 5 1 8
5 3 7 2 6 4 8 1
2 6
8 1
7 9
12 -3
0 8
99 99

Sample Output:

LCA of 2 and 6 is 3.
8 is an ancestor of 1.
ERROR: 9 is not found.
ERROR: 12 and -3 are not found.
ERROR: 0 is not found.
ERROR: 99 and 99 are not found.

实现思路:

根据先序和中序来建立一棵树,并且采用递归方式的LCA,来查找所要寻找的两个结点的最近公共祖先,类似题目是1143,但是上一题是BST寻找最近公共祖先,本题是一棵
普通二叉树来寻找,LCA递归函数中两个判断点(若所给两个结点值为p和q):
1.找到值为p或q的结点时返回当前值
2.当左右子树分别找到pq所对应结点时则返回当前结点所对应的值则为最近公共祖先结点

AC代码

#include <iostream>
#include <unordered_map>
using namespace std;
const int N=10010;
int n,m,in[N],pre[N];
unordered_map<int,int> mp;
struct node {
	int data;
	node *l,*r;
};


node* build(int preL,int preR,int inL,int inR) {
	if(preL>preR) return NULL;
	node *root=new node;
	root->data=pre[preL];
	mp[root->data]=1;
	int k;
	for(k=inL; k<=inR; k++) {
		if(in[k]==root->data) break;
	}
	int leftNodeNum=k-inL;
	root->l=build(preL+1,preL+leftNodeNum,inL,k-1);
	root->r=build(preL+leftNodeNum+1,preR,k+1,inR);
	return root;
}

int LCA(node *root,int p,int q) {
	if(root==NULL) return -1;
	int l=LCA(root->l,p,q);
	int r=LCA(root->r,p,q);
	if(root->data==p||root->data==q) return root->data==p?p:q;//找到p或者q所对应结点时 
	if(l!=-1&&r!=-1) return root->data;//pq分处在当前结点左右子树的情况
	return l!=-1?l:r;//哪棵子树找到祖先结点了就返回哪个结果
}

int main() {
	cin>>m>>n;
	for(int i=0; i<n; i++) scanf("%d",&in[i]);
	for(int i=0; i<n; i++) scanf("%d",&pre[i]);
	node *root=build(0,n-1,0,n-1);
	while(m--) {
		int a,b;
		scanf("%d%d",&a,&b);
		if(mp.count(a)==0||mp.count(b)==0) {
			if(mp.count(a)==0&&mp.count(b)==0) printf("ERROR: %d and %d are not found.",a,b);
			else if(mp.count(a)==0) printf("ERROR: %d is not found.",a);
			else printf("ERROR: %d is not found.",b);
		} else {
			int ans=LCA(root,a,b);
			if(ans==a||ans==b) printf("%d is an ancestor of %d.",ans==a?a:b,ans==a?b:a);
			else printf("LCA of %d and %d is %d.",a,b,ans);
		}
		printf("\n");
	}
	return 0;
}
posted @ 2021-02-10 21:10  coderJ_ONE  阅读(61)  评论(0)    收藏  举报