思路:
- 根据先序序列和中序序列建树
- 对于每对数字,分别记录它们的路径
- 找到最低公共结点
代码:
#include<cstdio>
#include<unordered_map>
#include<vector>
using namespace std;
int pairNum, keyNum;
int inorder[10001], preorder[10001];
unordered_map<int, int> posInInorder;
struct node {
int val;
node *left, *right;
node(int v) {
val = v;
left = NULL;
right = NULL;
}
}*root = NULL;
void buildTree(node *&cur, int preLeft, int preRight, int inLeft, int inRight) {
if (inLeft > inRight)
return;
cur = new node(preorder[preLeft]);
int pos = posInInorder[preorder[preLeft]];
int leftNum = pos - inLeft, rightNum = inRight - pos;
buildTree(cur->left, preLeft + 1, preLeft + leftNum, inLeft, pos - 1);
buildTree(cur->right, preRight - rightNum + 1, preRight, pos + 1, inRight);
}
void traverse(node *cur) {
if (cur == NULL)
return;
printf("%d", cur->val);
traverse(cur->left);
traverse(cur->right);
}
vector<int> getPath(int val) {
vector<int> path;
node *temp = root;
while (temp->val != val) {
path.push_back(temp->val);
if (posInInorder[val] < posInInorder[temp->val]) {
temp = temp->left;
}
else temp = temp->right;
}
path.push_back(val);
return path;
}
int main() {
scanf("%d %d", &pairNum, &keyNum);
for (int i = 0;i < keyNum;i++) {
scanf("%d", &inorder[i]);
posInInorder[inorder[i]] = i;
}
for (int i = 0;i < keyNum;i++) {
scanf("%d", &preorder[i]);
}
buildTree(root, 0, keyNum - 1, 0, keyNum - 1);
for (int i = 0;i < pairNum;i++) {
int a, b;
scanf("%d %d", &a, &b);
if (posInInorder.count(a) == 0 || posInInorder.count(b) == 0) {
if (posInInorder.count(a) == 0 && posInInorder.count(b) == 0) {
printf("ERROR: %d and %d are not found.\n", a, b);
}
else if (posInInorder.count(a) == 0) {
printf("ERROR: %d is not found.\n", a);
}
else if (posInInorder.count(b) == 0) {
printf("ERROR: %d is not found.\n", b);
}
continue;
}
vector<int> pa = getPath(a), pb = getPath(b);
int index = 0;
while (index < pa.size() && index < pb.size() && pa[index] == pb[index])
index++;
index--;
if (pa[index] == a) {
printf("%d is an ancestor of %d.\n", a, b);
}
else if (pa[index] == b) {
printf("%d is an ancestor of %d.\n", b, a);
}
else {
printf("LCA of %d and %d is %d.\n", a, b, pa[index]);
}
}
return 0;
}
二刷:
思路同1143 Lowest Common Ancestor (30分)最底部解法:
#include<iostream>
#include<vector>
#include<unordered_map>
#include<algorithm>
using namespace std;
vector<int> inorder, preorder;
unordered_map<int, int> inIndex;
int main() {
int numTest, numNode;
cin >> numTest >> numNode;
inorder.resize(numNode);
preorder.resize(numNode);
for (int i = 0; i < numNode; i++) {
cin >> inorder[i];
inIndex[inorder[i]] = i;
}
for (int i = 0; i < numNode; i++) {
cin >> preorder[i];
}
for (int i = 0; i < numTest; i++) {
int a, b;
cin >> a >> b;
for (int j = 0; j < numNode; j++) {
int num = preorder[j];
int pos = inIndex[num];
if (inIndex.count(a) == 0 && inIndex.count(b) == 0) {
printf("ERROR: %d and %d are not found.\n", a, b);
break;
}
else if (inIndex.count(a) == 0 || inIndex.count(b) == 0) {
printf("ERROR: %d is not found.\n", inIndex.count(a) == 0? a: b);
break;
}
if (pos > min(inIndex[a], inIndex[b]) && pos < max(inIndex[a], inIndex[b])) {
printf("LCA of %d and %d is %d.\n", a, b, num);
break;
}
else if (num == a) {
printf("%d is an ancestor of %d.\n", a, b);
break;
}
else if (num == b) {
printf("%d is an ancestor of %d.\n", b, a);
break;
}
}
}
}