PAT1143 &1151 找LCA问题(刷题记录)

  1. About Questions
    These two questions are similar.Both of them give traversal sequence of a binary tree and asks us to find the LCA(Lowest Common Ancestor) of some query pairs.
  2. 1143 Lowest Common Ancestor (30point(s))
    According to the preorder traversal sequence of the searching binary tree, we can create this BST (that is to get its nodes’ parent and their level to store in maps).Then according to the information we’ve collected, we can find any nodes pair’s LCA(function void findLCA(int n1, int n2)).
    `The first time I submitted my code,there exists Time Limitted Exceeded error .So I change every “cin” to “scanf” and map to unordered_map,then it is accepted.
  3. 1151 LCA in a Binary Tree (30point(s))
    In this question,we need to create a binary tree(not BST) based on its inoeder and preorder traversal sequences.

PAT 1143

#include <iostream>
#include <stdio.h>
#include<stdlib.h>
#include <math.h>
#include <algorithm>
#include <vector>
#include <map>
#include <string>
#include<stack>
#include <unordered_map>
#include <set>

using namespace std;

const int maxn = 10100;

int M, N;
int pre[maxn];
unordered_map<int, int> depth;
unordered_map<int, int> parent;
//set<int> keys;

void bst()
{
	stack<int> S;
	S.push(pre[0]);
	depth[pre[0]] = 0;
	for (int i = 1; i < N; i++)
	{
		if (pre[i] < S.top()) {
			parent[pre[i]] = S.top();
			depth[pre[i]] = depth[S.top()] + 1;
			S.push(pre[i]);
		}
		else {
			int tmp;
			while (!S.empty() && pre[i] >= S.top())
			{
				tmp = S.top();
				S.pop();
			}
			parent[pre[i]] = tmp;
			depth[pre[i]] = depth[tmp] + 1;
			S.push(pre[i]);
		}
	}

}

void findLCA(int n1, int n2)
{
	if (!depth.count(n1) && !depth.count(n2)) printf("ERROR: %d and %d are not found.\n", n1, n2);
	else if (!depth.count(n1)) printf("ERROR: %d is not found.\n", n1);
	else if (!depth.count(n2)) printf("ERROR: %d is not found.\n", n2);
	else {
		int n3 = n1, n4 = n2;
		if (depth[n3] != depth[n4]) { //n3始终是深度小的那个节点
			if (depth[n1] > depth[n2]) { n3 = n2; n4 = n1; }
			//int n3=n2;
			for (int d = depth[n4] - 1; d >= depth[n3]; d--)
			{
				n4 = parent[n4];
				if (n4 == n3)  break;

			}
		}
		if (n4 == n3) {
			if (depth[n1] > depth[n2]) printf("%d is an ancestor of %d.\n", n2, n1);
			else printf("%d is an ancestor of %d.\n", n1, n2);
		}
		else {
			for (int i = depth[n3] - 1; i >= 0; i--)
			{
				n3 = parent[n3];
				n4 = parent[n4];
				if (n3 == n4) { printf("LCA of %d and %d is %d.\n", n1, n2, n3); break; }

			}
		}
	}
}

int main() {

	//cin >> M >> N;
    scanf("%d%d",&M,&N);
	for (int i = 0; i < N; i++)
	{
		//cin >> pre[i];
        scanf("%d",pre+i);
		//keys.insert(pre[i]);
	}

	bst();

	int n1, n2;
	for (int i = 0; i < M; i++)
	{
		scanf("%d%d",&n1,&n2);
        //cin >> n1 >> n2;
		findLCA(n1, n2);
	}
	
	return 0;

}

PAT 1151

#include <iostream>
#include <stdio.h>
#include<stdlib.h>
#include <math.h>
#include <algorithm>
#include <vector>
#include <map>
#include <string>
#include<queue>
#include <unordered_map>
#include <set>

using namespace std;

const int maxn = 11000;

int in[maxn];
int pre[maxn];
map<int, int> parent;
map<int,int> depth;
set<int> keys;

int bt(int l1, int r1, int l2, int r2,int dep)
{
	if (l1 > r1) return -1;
	int rt = pre[l2];
	depth[rt] = dep;
	int pos=l1;
	for (int i = l1; i <= r1; i++) {
		if (in[i] == rt) { pos = i; break; }
	}
	int lr = bt(l1, pos - 1, l2 + 1, l2 + pos - l1, dep + 1);
	parent[lr] = rt;
	int rr = bt(pos + 1, r1, l2 + pos-l1+1, r2, dep+1);
	//parent[lr] = rt;
	parent[rr] = rt;

	return rt;
}

void findLCA(int n1, int n2)
{
	if (!keys.count(n1) && !keys.count(n2)) printf("ERROR: %d and %d are not found.\n",n1,n2);
	else if (!keys.count(n1)) printf("ERROR: %d is not found.\n", n1);
	else if (!keys.count(n2)) printf("ERROR: %d is not found.\n", n2);
	else {
		int n3=n1 , n4=n2 ;
		if (depth[n3] != depth[n4]) { //n3始终是深度小的那个节点
			if (depth[n1] > depth[n2]) { n3 = n2; n4 = n1; }
			//int n3=n2;
			for (int d = depth[n4] - 1; d >= depth[n3]; d--)
			{
				n4 = parent[n4];
				if (n4 == n3)  break; 
				
			}
			}
		if (n4 == n3) {
			if (depth[n1] > depth[n2]) printf("%d is an ancestor of %d.\n", n2, n1);
			else printf("%d is an ancestor of %d.\n", n1, n2);
		}
		else {
			for (int i = depth[n3] - 1; i >= 0; i--)
			{
				n3 = parent[n3];
				n4 = parent[n4];
				if (n3 == n4) { printf("LCA of %d and %d is %d.\n", n1, n2, n3); break; }

			}
		}
	}
}

int main() {

	int M, N;
	cin >> M >> N;
	for (int i = 0; i < N; i++)
	{
		cin >> in[i];
		keys.insert(in[i]);
	}
	for (int i = 0; i < N; i++)
	{
		cin >> pre[i];
	}
	
	bt(0, N - 1, 0, N - 1, 0);


	int n1, n2;
	for(int i=0;i<M;i++)
	{
		cin >> n1 >> n2;
		//cout << n1 << " " << n2 << endl;
		//cout << depth[n1] << " " << depth[n2] << endl;
		findLCA(n1, n2);
	}

	return 0;

}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值