题意:根据前序和中序建立树,寻找两个点的LCA。

我在之前的博客中写了关于LCA的多种求法。 https://www.cnblogs.com/yy-1046741080/p/11505547.html。  在建树的过程中,建立深度和parent,来寻找LCA。

该题目的数据有一定的欺诈性,它给你结点数据是1-8,如果没有仔细看清题目,那么很有可能定义一个 node tree[10005]的数组,但是题目并没有说数据范围在1-10000内。

经过测试,如果你将范围定义稍微大一点,还是能全过的;

我在这里采用的就是二叉链表,使用二叉链表麻烦的一点在于,需要查找u,v两个结点,返回其指针。

我认为最好的方法就是建立一个映射表,映射输入data和node tree[]中下标的关系,就不需要进行查找。

 #include<bits/stdc++.h>
using namespace std; struct node {
int data;
struct node* left, * right; //left/right=-1,表示空子树
int depth;
struct node* parent;
}; node* root; // 树的根
int pre[]; // 先序遍历序列
int in[]; // 后序遍历序列
set<int> is_visit; // 先序序列pre[preL,preR],中序序列in[inL,inR], depth/parent:for LCA;
node* BuildTree(int preL, int preR, int inL, int inR, int depth, node* parent) {
if (preL > preR) {
return NULL;
}
node* root = new node;
root->data = pre[preL];
root->depth = depth;
root->parent = parent;
int k;
for (k = inL; in[k] != pre[preL]; k++) {
;
}
root->left = BuildTree(preL + , preL + k - inL, inL, k - , depth + , root);
root->right = BuildTree(preL + k - inL + , preR, k + , inR, depth + , root); return root; // 返回
} // 寻找权值为value的结点
void find(node* root, int value,node* &t) {
if (root != NULL) {
if (root->data == value) {
t = root;
}
else {
find(root->left, value,t);
find(root->right, value,t);
}
}
} int LCA(int u, int v) {
node* uu;
find(root, u, uu);
node* vv;
find(root, v, vv);
while (uu->depth > vv->depth) {
uu = uu->parent;
}
while (uu->depth < vv->depth) {
vv = vv->parent;
}
while (uu != vv) {
uu = uu->parent;
vv = vv->parent;
}
return uu->data;
} int main() {
int N, M;
cin.sync_with_stdio(false);
cin >> N >> M;
for (int i = ; i <= M; i++) {
cin >> in[i];
is_visit.insert(in[i]);
}
for (int i = ; i <= M; i++) {
cin >> pre[i];
}
root = BuildTree(, M, , M, , NULL);
while (N--) {
int u, v;
cin >> u >> v;
bool f1 = is_visit.find(u) != is_visit.end() ? true : false;
bool f2 = is_visit.find(v) != is_visit.end() ? true : false; if (!f1 && !f2) {
cout << "ERROR: " << u << " and " << v << " are not found.\n";
}
else if (!f1) {
cout << "ERROR: " << u <<" is not found.\n";
}
else if (!f2) {
cout << "ERROR: " << v <<" is not found.\n";
}
else {
int w = LCA(u, v);
if (w == u) {
cout << u << " is an ancestor of " << v << ".\n";
}
else if (w == v) {
cout << v << " is an ancestor of " << u << ".\n";
}
else {
cout << "LCA of " << u << " and " << v << " is " << w << ".\n";
}
}
}
}

PATA-1151 LCA in a Binary Tree的更多相关文章

  1. PAT 1151 LCA in a Binary Tree[难][二叉树]

    1151 LCA in a Binary Tree (30 分) The lowest common ancestor (LCA) of two nodes U and V in a tree is ...

  2. 【PAT 甲级】1151 LCA in a Binary Tree (30 分)

    题目描述 The lowest common ancestor (LCA) of two nodes U and V in a tree is the deepest node that has bo ...

  3. PAT 甲级 1151 LCA in a Binary Tree

    https://pintia.cn/problem-sets/994805342720868352/problems/1038430130011897856 The lowest common anc ...

  4. 1151 LCA in a Binary Tree(30 分)

    The lowest common ancestor (LCA) of two nodes U and V in a tree is the deepest node that has both U ...

  5. PAT Advanced 1151 LCA in a Binary Tree (30) [树的遍历,LCA算法]

    题目 The lowest common ancestor (LCA) of two nodes U and V in a tree is the deepest node that has both ...

  6. 1151 LCA in a Binary Tree

    The lowest common ancestor (LCA) of two nodes U and V in a tree is the deepest node that has both U ...

  7. 1151 LCA in a Binary Tree (30point(s))

    The lowest common ancestor (LCA) of two nodes U and V in a tree is the deepest node that has both U ...

  8. PAT甲级|1151 LCA in a Binary Tree 先序中序遍历建树 lca

    给定先序中序遍历的序列,可以确定一颗唯一的树 先序遍历第一个遍历到的是根,中序遍历确定左右子树 查结点a和结点b的最近公共祖先,简单lca思路: 1.如果a和b分别在当前根的左右子树,当前的根就是最近 ...

  9. PAT_A1151#LCA in a Binary Tree

    Source: PAT A1151 LCA in a Binary Tree (30 分) Description: The lowest common ancestor (LCA) of two n ...

  10. PAT-1151(LCA in a Binary Tree)+最近公共祖先+二叉树的中序遍历和前序遍历

    LCA in a Binary Tree PAT-1151 本题的困难在于如何在中序遍历和前序遍历已知的情况下找出两个结点的最近公共祖先. 可以利用据中序遍历和前序遍历构建树的思路,判断两个结点在根节 ...

随机推荐

  1. 07.JS对象-2

    前言: 学习一门编程语言的基本步骤(01)了解背景知识(02)搭建开发环境(03)语法规范(04)常量和变量(05)数据类型(06)数据类型转换(07)运算符(08)逻辑结构(09)函数(10)对象1 ...

  2. 教你一种简单方法给word和PDF格式的文件使用电子签名

      前言  虽然还处在非常时期,但很多公司已陆陆续续复工或准备复工.   上周,人事妹纸给了我们一份,企业员工健康情况申报表.具体如下 现在问题来了,需要本人签名,电脑打上去的不算,需要手写. 此时, ...

  3. 高级UI组件

    1.进度条 (1).圆形进度条(一般默认为圆形进度条) <ProgressBar android:layout_width="wrap_content" android:la ...

  4. GCD相关

    板子: ? gcd(b, a % b) : a; } POJ1930 题意:给你一个无限循环小数,给到小数点后 9 位,要求这个数的分数形式. 解法: 要想解决这道题,首先应该了解如何将循环小数化为分 ...

  5. lucas定理及其拓展的推导

    lucas定理及其拓展的推导 我的前一篇博客-- lucas定理 https://mp.csdn.net/mdeditor/100550317#主要是给出了lucas的结论和模板,不涉及推导. 本篇文 ...

  6. SP1805 HISTOGRA - Largest Rectangle in a Histogram

    --------------------------------------------------- 我就是想学个单调栈然后全网都是个蓝题 ----------------------------- ...

  7. CF 150E Freezing with Style [长链剖分,线段树]

    \(sol:\) 给一种大常数 \(n \log^2 n\) 的做法 考虑二分,由于是中位数,我们就二分这个中位数,\(x>=mid\)则设为 \(1\),否则为 \(-1\) 所以我们只需要找 ...

  8. vue.config.js添加路径别名

    在组件库中添加配置文件后其它文件需要引用它,此时想到利用路径的别名比较方便,相当于缩写了,请看下面的添加过程: (一)在vue.config.js文件中添加的内容如粗体字体所示: const path ...

  9. Kali Linux中Chrome浏览器不能启动的问题

    kali中自带了Chromium Web Browser,我点了几次没反应.我还以为是Chrome的版本问题.于是下载了Chrome的deb包. 安装中还解决了一个包依赖问题.安装成功还是不能启动.于 ...

  10. const 函数

    const int *p   // 修饰*p ,p指针可以变,但是*p的值不变 例子: int a = 5; int b = 10; const *p = &a; *p = 10: // 不可 ...