题意:根据前序和中序建立树,寻找两个点的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. MySQL 普通索引和唯一索引的区别

    该文为< MySQL 实战 45 讲>的学习笔记,感谢查看,如有错误,欢迎指正 一.查询和更新上的区别 这两类索引在查询能力上是没差别的,主要考虑的是对更新性能的影响.建议尽量选择普通索引 ...

  2. mysql必知必会--创建计算字段

    计算字段 存储在数据库表中的数据一般不是应用程序所需要的格式.下面举 几个例子. * 如果想在一个字段中既显示公司名,又显示公司的地址,但这两 个信息一般包含在不同的表列中. * 城市.州和邮政编码存 ...

  3. Android进程调度之adj算法

    copy from : http://gityuan.com/2016/08/07/android-adj/ 一.概述 提到进程调度,可能大家首先想到的是Linux cpu调度算法,进程优先级之类概念 ...

  4. 在本地搭建git服务器

    GitHub就是一个免费托管开源代码的远程仓库.但是对于某些视源代码如生命的商业公司来说,既不想公开源代码,又舍不得给GitHub交保护费,那就只能自己搭建一台Git服务器作为私有仓库使用. 搭建Gi ...

  5. Mysql 两种引擎的区别

    MyISAM与InnoDB的区别是什么? 1. 存储结构 MyISAM:每个MyISAM在磁盘上存储成三个文件.第一个文件的名字以表的名字开始,扩展名指出文件类型..frm文件存储表定义.数据文件的扩 ...

  6. Jstree在加载时和加载完成的回调方法-sunziren

    1.有时候在使用jstree的时候我们想在它加载完成后立刻执行某个方法,于是我们可以用下面这个jstree自带的回调: .on('ready.jstree', function(event, obj) ...

  7. maven的核心概念——仓库

    第十章仓库 10.1 分类 [1]本地仓库:为当前本机电脑上的所有Maven工程服务. [2]远程仓库 (1)私服:架设在当前局域网环境下,为当前局域网范围内的所有Maven工程服务. (2)中央仓库 ...

  8. 3个N加上各种运算符号结果等于6(纯属娱乐)C#

    网上的题目: 题有点难  但都有解 2    2    2  =  6 3    3    3  =  6 4    4    4  =  6 5    5    5  =  6 6    6     ...

  9. VSCode部署JAVA项目出现The type java.lang.Object cannot be resolved

    如题,出现的原因是这样的:我将mac系统上的eclipse项目复制到了ubuntu环境下,通过vscode的远程功能连接ubuntu. 然后项目上就出现了各种报错,显示The type java.la ...

  10. 小程序onShow事件获取options方法

    微信小程序 onShow() 事件 onShow() 事件不接受参数,因此无法获取页面 url 传递过来的参数,只有 onLoad() 事件可以. onShow(options){ console.l ...