【题解】【AcWing】1644. 二叉树中的最低公共祖先

202 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

1644. 二叉树中的最低公共祖先

原题传送:AcWing 1644. 二叉树中的最低公共祖先

树中两个结点 UUVV 的最低公共祖先(LCA)是指同时具有 UUVV 作为后代的最深结点。

给定二叉树中的任何两个结点,请你找到它们的LCA。

输入格式

第一行包含两个整数 MMNN ,分别表示询问结点对数以及二叉树中的结点数量。

接下来两行,每行包含 NN 个不同的整数,分别表示二叉树的中序和前序遍历。

保证二叉树可由给定遍历序列唯一确定。

接下来 MM 行,每行包含两个整数 UUVV ,表示一组询问。

所有结点权值均在int范围内。

输出格式

对于每对给定的 UUVV ,输出一行结果。

如果 UUVV 的LCA是 AA ,且 AA 不是 UUVV ,则输出LCA of U and V is A.

如果 UUVV 的LCA是 AA ,且 AAUUVV 中的一个,则输出X is an ancestor of Y.,其中 XX 表示 AAYY 表示另一个结点。

如果 UUVV 没有在二叉树中找到,则输出ERROR: U is not found.ERROR: V is not found.ERROR: U and V are not found.

数据范围

1M10001 \le M \le 1000 , 1N100001 \le N \le 10000

输入样例:

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

输出样例:

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.

思路:

前序遍历和中序遍历建树,离散化下标,保存每个点的父结点和对应的深度,从高到低寻找相同结点即为最低公共祖先。

题解:

#include<bits/stdc++.h>

using namespace std;

const int N = 10010;

int m, n;
int pre[N], in[N], seq[N];
int p[N], depth[N];
unordered_map<int, int> pos;

int build(int il, int ir, int pl, int pr, int d)
{
	int root = pre[pl];
	int k = root;
	
	depth[root] = d;
	
	if(il < k)
		p[build(il, k - 1, pl + 1, pl + 1 + (k - 1 - il), d + 1)] = root;
	if(k < ir)
		p[build(k + 1, ir, pl + 1 + (k - 1 - il) + 1, pr, d + 1)] = root;
	return root;
}

int main()
{	
	cin >> m >> n;

	for(int i = 0; i < n; i++)
	{
		cin >> seq[i];
		pos[seq[i]] = i;
		in[i] = i;
	}
	for(int i = 0; i < n; i++)
	{
		cin >> pre[i];
	}	
	
	for (int i = 0; i < n; i ++ )
		pre[i] = pos[pre[i]];

	build(0, n - 1, 0, n - 1, 0);
	
	while(m--)
	{
		int a, b;
		cin >> a >> b;
		
		if(pos.count(a) && pos.count(b))
		{
			a = pos[a], b = pos[b];
			int x = a, y = b;
			while(a != b)
			{
				if(depth[a] < depth[b])
					b = p[b];
				else
					a = p[a];
			}
			
			if(a != x && a != y)
				cout << "LCA of " << seq[x] << " and " << seq[y] << " is " << seq[a] << "." << endl;
			else if(a == x)
				cout << seq[x] << " is an ancestor of " << seq[y] << "." << endl;
			else
				cout << seq[y] << " is an ancestor of " << seq[x] << "." << endl;
		}
		else if(pos.count(a) == 0 && pos.count(b) == 0)
			cout << "ERROR: " << a << " and " << b << " are not found." << endl;
		else if(pos.count(a) == 0)
			cout << "ERROR: " << a << " is not found." << endl;
		else
			cout << "ERROR: " << b << " is not found." << endl;
	}
	
	return 0;
}