当前位置: 代码迷 >> 综合 >> 1151 LCA in a Binary Tree (30分)
  详细解决方案

1151 LCA in a Binary Tree (30分)

热度:46   发布时间:2023-11-20 11:45:09.0

在这里插入图片描述

自己写的:

先建树,然后利用后续非递归遍历求解

#include<iostream>
#include<stack>
using namespace std;
const int maxn = 10010;
typedef struct node {
    int n;node* left;node* right;
}*tree;
int n, m, pre[maxn], in[maxn];
tree createT(int preS, int preE, int inS, int inE) {
    if (preS > preE)return NULL;tree root = new node;root->n = pre[preS];int pos = inS;for (int i = inS; i <= inE; i++) {
    if (in[i] == pre[preS]) {
    pos = i;break;}}int length = pos - inS;root->left = createT(preS + 1, preS + length, inS, pos - 1);root->right = createT(preS + length + 1, preE, pos + 1, inE);return root;
}
int getAns(int u, int v, tree t) {
    tree stack[maxn], temp[maxn];int top = -1, tempTop = -1;tree p = t, pre = NULL;while (p != NULL || top != -1) {
    while (p != NULL) {
    stack[++top] = p;p = p->left;}if (top != -1) {
    p = stack[top];if (p->right != NULL && p->right != pre) {
    p = p->right;}else {
    if ((p->n == u) || (p->n == v)) {
    if (tempTop == -1) {
    for (int i = 0; i <= top; i++) {
    tempTop++;temp[tempTop] = stack[tempTop];}}else {
    int length = (top < tempTop) ? top : tempTop;for (int i = length; i >= 0; i--) {
    if (stack[i]->n == temp[i]->n) {
    return stack[i]->n;}}}}top--;pre = p;p = NULL;}}}
}
int main() {
    cin >> m >> n;for (int i = 0; i < n; i++)cin >> in[i];for (int i = 0; i < n; i++)cin >> pre[i];tree t = createT(0, n - 1, 0, n - 1);for (int i = 0; i < m; i++) {
    int u, v;cin >> u >> v;bool findu = false, findv = false;for (int j = 0; j < n; j++) {
    if (pre[j] == u)findu = true;if (pre[j] == v)findv = true;}if (findu == false && findv == false) {
    printf("ERROR: %d and %d are not found.\n", u, v);continue;}if (findu == false) {
    printf("ERROR: %d is not found.\n", u);continue;}if (findv == false) {
    printf("ERROR: %d is not found.\n", v);continue;}int ans = getAns(u, v, t);if (u == v) {
    printf("%d is an ancestor of %d.\n", u, v);continue;}if (ans != u && ans != v) {
    printf("LCA of %d and %d is %d.\n", u, v, ans);continue;}if (ans == u) {
    printf("%d is an ancestor of %d.\n", u, v);continue;}if (ans == v) {
    printf("%d is an ancestor of %d.\n", v, u);continue;}}
}

看了大佬答案后写的:

PAT 1151 LCA in a Binary Tree(30 分)- 甲级
不需要建树,在中序序列中,如果u和v的位置在当前节点root的位置的左边,则lca在root的左子树中,如果u和v的位置在当前节点root的位置的右边,则lca在root的右子树中,否则,u和v在root两侧,那么root就是lca。
关键在于记录每个节点在中序序列中的位置。

#include<iostream>
#include<map>
using namespace std;
const int maxn = 1010;
int pre[maxn], in[maxn], m, n;
map<int, int>pos;//记录各个节点在中序序列中的位置void lca(int inS, int inE, int root, int u, int v) {
    //root是中序序列中[inS,inE]这一部分子树的根//在先序序列中的位置if (inS > inE)return;int rootPos = pos[pre[root]];//求## 标题子树根在中序序列中的位置int uPos = pos[u];int vPos = pos[v];if (uPos < rootPos && vPos < rootPos)lca(inS, rootPos - 1, root + 1, u, v);else if (uPos > rootPos&& vPos > rootPos)lca(rootPos + 1, inE, root + rootPos - inS + 1, u, v);else if ((uPos<rootPos && vPos>rootPos) || (uPos > rootPos&& vPos < rootPos))printf("LCA of %d and %d is %d.\n", u, v, pre[root]);else if (uPos == rootPos)printf("%d is an ancestor of %d.\n", u, v);else if (vPos == rootPos) {
    printf("%d is an ancestor of %d.\n", v, u);}
}
int main() {
    cin >> m >> n;for (int i = 1; i <= n; i++) {
    cin >> in[i];pos[in[i]] = i;}for (int i = 1; i <= n; i++)cin >> pre[i];for (int i = 0; i < m; i++) {
    int u, v;cin >> u >> v;if (pos.count(u) == 0 && pos.count(v) == 0)printf("ERROR: %d and %d are not found.\n", u, v);else if (pos.count(u) == 0 || pos.count(v) == 0)printf("ERROR: %d is not found.\n", pos.count(u) == 0 ? u : v);elselca(1, n, 1, u, v);}return 0;
}

注意:u和v相等且都在树中时,输出格式是:u is an ancestor of u.而不是LCA of u and u is u.这里写错会导致第二个测点不通过

递归求LCA,还是比较容易理解的。
(二叉树)二叉树的最近公共祖先

tree lca(tree root, tree p, tree q) {
    //这里假设p和q都在树上if(root==p||root==q||!root)return root;tree left=lca(root->left,  p, q);tree right=lca(root->right,  p, q);    if(!left&&!right)return NULL;//左右子树都没有找到p和qelse if(left&&!right)return left;//。。。else if(right&&!left)return right; //。。。else							//p和q分属左右子树的情况return root;}

我好菜呀

  相关解决方案