【笨方法学PAT】1143 Lowest Common Ancestor (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.

A binary search tree (BST) is recursively defined as a binary tree which has the following properties:

  • The left subtree of a node contains only nodes with keys less than the node's key.
  • The right subtree of a node contains only nodes with keys greater than or equal to the node's key.
  • Both the left and right subtrees must also be binary search trees.

Given any two nodes in a BST, 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 BST, respectively. In the second line, N distinct integers are given as the preorder traversal sequence of the BST. 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 BST, 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
6 3 1 2 5 4 8 7
2 5
8 7
1 9
12 -3
0 8
99 99

Sample Output:

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

二、题目大意

题目大意是找出句中出现次数最多的单词,并输出。。

三、考点

寻找最近祖先

四、注意

1、前序遍历,最开始的就是根;

2、从根开始,找到一个节点node,使得a b分别在两边,node就是所求的节点;

3、从pre[0]开始寻找即可。

五、代码 

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<vector>
#include<unordered_map>
#include<algorithm>
using namespace std;

vector<int> pre;
int m, n;

int main() {
	//read
	cin >> m >> n;
	pre.resize(n);
	//set<int> sset;
	unordered_map<int, int> un_map;
	for (int i = 0; i < n; ++i) {
		//cin >> pre[i];
		scanf("%d", &pre[i]);
		un_map[pre[i]] = 1;
	}

	//find lca
	while (m--) {
		int a, b;
		//cin >> a >> b;
		scanf("%d %d", &a, &b);

		//not found
		if (un_map.find(a) == un_map.end() && un_map.find(b) == un_map.end()) {
			printf("ERROR: %d and %d are not found.\n", a, b);
			continue;
		}
		else if (un_map.find(a) == un_map.end() && un_map.find(b) != un_map.end()) {
			printf("ERROR: %d is not found.\n", a);
			continue;
		}
		else if (un_map.find(a) != un_map.end() && un_map.find(b) == un_map.end()) {
			printf("ERROR: %d is not found.\n", b);
			continue;
		}

		//lca
		int lca;
		int index = 0;
		while (index != n) {
			if (pre[index] >= a && pre[index] <= b|| pre[index] <= a && pre[index] >= b) {
				lca = pre[index];
				break;
			}
			index++;
		}

		if (lca != a && lca != b)
			printf("LCA of %d and %d is %d.\n", a, b, lca);
		else if (lca == a)
			printf("%d is an ancestor of %d.\n", a, b);
		else if(lca==b)
			printf("%d is an ancestor of %d.\n", b, a);
	}

	system("pause");
	return 0;
}

六、建树会超时

 

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<vector>
#include<unordered_map>
#include<algorithm>
using namespace std;
struct node {
	int val;
	struct node *left, *right;
};
vector<int> pre;

node* buildTree(node *root, int val) {
	if (root == NULL) {
		node *tree = new node();
		tree->val = val;
		tree->left = tree->right = NULL;
		return tree;
	}
	if (val < root->val)
		root->left = buildTree(root->left, val);
	else if (val > root->val)
		root->right = buildTree(root->right, val);
	return root;
}

void dfs(node *root) {
	if (root == NULL)
		return;
	cout << root->val <<endl;
	dfs(root->left);
	dfs(root->right);
}

int findLCA(node *root, int a, int b) {
	if (root != NULL) {
		int val = root->val;

		if (a > b)
			swap(a, b);

		if (val >= a && val <= b)
			return val;
		else if (val < a)
			return findLCA(root->right, a, b);
		else if (val > b)
			return findLCA(root->left, a, b);
	}
	
}

int main() {
	//read
	int m, n;
	cin >> m >> n;
	pre.resize(n);
	node *root = NULL;
	//set<int> sset;
	unordered_map<int, bool> un_map;
	for (int i = 0; i < n; ++i) {
		//cin >> pre[i];
		scanf("%d", &pre[i]);
		un_map[pre[i]]=1;
		root = buildTree(root, pre[i]);
	}
	
	//judge
	//dfs(root);

	//find lca
	while (m--) {
		int a, b;
		//cin >> a >> b;
		scanf("%d %d", &a, &b);

		//not found
		if (un_map.find(a) == un_map.end() && un_map.find(b) == un_map.end()) {
			printf("ERROR: %d and %d are not found.\n", a, b);
			continue;
		}
		else if (un_map.find(a) == un_map.end() && un_map.find(b) != un_map.end()) {
			printf("ERROR: %d is not found.\n", a);
			continue;
		}
		else if (un_map.find(a) != un_map.end() && un_map.find(b) == un_map.end()) {
			printf("ERROR: %d is not found.\n", b);
			continue;
		}

		//lca
		int lca = findLCA(root, a, b);

		if (lca != a && lca != b)
			printf("LCA of %d and %d is %d.\n", a, b, lca);
		else if (lca == a)
			printf("%d is an ancestor of %d.\n", a, b);
		else if(lca==b)
			printf("%d is an ancestor of %d.\n", b, a);
	}

	system("pause");
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值