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.

Given any two nodes in a binary tree, 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 binary tree, respectively. In each of the following two lines, N distinct integers are given as the inorder and preorder traversal sequences of the binary tree, respectively. It is guaranteed that the binary tree can be uniquely determined by the input sequences. 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 binary tree, 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
7 2 3 4 6 5 1 8
5 3 7 2 6 4 8 1
2 6
8 1
7 9
12 -3
0 8
99 99

Sample Output:

LCA of 2 and 6 is 3.
8 is an ancestor of 1.
ERROR: 9 is not found.
ERROR: 12 and -3 are not found.
ERROR: 0 is not found.
ERROR: 99 and 99 are not found.
有一道考研题也是求lca,突然想到一个不用建树的方法,不过要额外小心细节,避免超时。依然用map记录元素在中序遍历数组中位置,下标不为0,如下:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <map>
using namespace std;
int pre[],in[],m,n;
map<int,int> mp;
void check(int a,int b) {
int aa = mp[a],bb = mp[b];
if(!bb && !aa)printf("ERROR: %d and %d are not found.\n",a,b);
else if(!aa)printf("ERROR: %d is not found.\n",a);
else if(!bb)printf("ERROR: %d is not found.\n",b);
else {
if(a == b) {
printf("%d is an ancestor of %d.\n",a,b);
return;
}
int p1 = ,p2 = n,i1 = ,i2 = n;
while(p1 <= p2) {
int temp = pre[p1],mtemp = mp[temp];
if(temp == a) {
printf("%d is an ancestor of %d.\n",a,b);
return;
}
else if(temp == b) {
printf("%d is an ancestor of %d.\n",b,a);
return;
}
if(mtemp > aa && mtemp > bb) i2 = mtemp - ,p1 ++,p2 = p1 + i2 - i1;
else if(mtemp < aa && mtemp < bb) i1 = mtemp + ,p1 = p2 - i2 + i1;
else {
printf("LCA of %d and %d is %d.\n",a,b,temp);
return;
}
}
}
}
int main() {
int a,b;
scanf("%d%d",&m,&n);
for(int i = ;i <= n;i ++) {
scanf("%d",&in[i]);
mp[in[i]] = i;
}
for(int i = ;i <= n;i ++) {
scanf("%d",&pre[i]);
}
for(int i = ;i < m;i ++) {
scanf("%d%d",&a,&b);
check(a,b);
}
return ;
}

给定一棵树的中序和前序遍历,要求查询两个点的最低祖先,需要记录高度。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <map>
using namespace std;
struct tree
{
int Data,Height;
tree *Last,*Left,*Right;
}*head;
int q[],z[],m,n;
map<int,tree *> mp;///根据序号映射到结点
tree *createNode(int d,int h)///创建新结点并返回
{
tree *p = new tree();
p -> Data = d;
mp[d] = p;
p -> Height = h;
p -> Last = p -> Left = p -> Right = NULL;
return p;
}
tree *createTree(int ql,int qr,int zl,int zr,int h)///前中序 还原树
{
tree *p = createNode(q[ql],h);
for(int i = zl;i <= zr;i ++)
{
if(z[i] == q[ql])
{
if(i > zl)p -> Left = createTree(ql + ,ql + i - zl,zl,i - ,h + ),p -> Left -> Last = p;
if(i < zr)p -> Right = createTree(ql + i - zl + ,qr,i + ,zr,h + ),p -> Right -> Last = p;
break;
}
}
return p;
}
void check(int a,int b)///判断两点
{
if(mp[a] == NULL && mp[b] == NULL)printf("ERROR: %d and %d are not found.\n",a,b);
else if(mp[a] == NULL)printf("ERROR: %d is not found.\n",a);
else if(mp[b] == NULL)printf("ERROR: %d is not found.\n",b);
else {
tree *t1 = mp[a],*t2 = mp[b];
while(t1 -> Height != t2 -> Height) {
if(t1 -> Height > t2 -> Height)t1 = t1 -> Last;
else t2 = t2 -> Last;
}///调整至高度相同
if(t1 == t2) {///一个点是另一个点的祖先
printf("%d is an ancestor of %d.\n",t1 -> Data,a == t1 -> Data ? b : a);
return;
}while(t1 != t2) {
t1 = t1 -> Last;
t2 = t2 -> Last;
}
printf("LCA of %d and %d is %d.\n",a,b,t1 -> Data);
}
}
int main() {
int a,b;
scanf("%d%d",&m,&n);
for(int i = ;i < n;i ++) {
scanf("%d",&z[i]);
}
for(int i = ;i < n;i ++) {
scanf("%d",&q[i]);
}
head = createTree(,n - ,,n - ,);
for(int i = ;i < m;i ++) {
scanf("%d%d",&a,&b);
check(a,b);
}
}

1151 LCA in a Binary Tree(30 分)的更多相关文章

  1. 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 ...

  2. 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 ...

  3. 【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 ...

  4. 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 ...

  5. PAT 甲级 1151 LCA in a Binary Tree

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

  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. PAT甲级|1151 LCA in a Binary Tree 先序中序遍历建树 lca

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

  8. 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 ...

  9. PTA 04-树6 Complete Binary Search Tree (30分)

    题目地址 https://pta.patest.cn/pta/test/16/exam/4/question/669 5-7 Complete Binary Search Tree   (30分) A ...

随机推荐

  1. 如何安装/更新ruby,安装cocoapods,为开发做好准备!(2016年12月07日更新内容)

    一:首先来说一下如何安装/更新ruby: 一般情况下,即使是新买的Mac电脑也会安装有ruby,可以在终端中键入一下命令查看ruby版本 ruby -v 正常情况下下面会打印出ruby的版本信息,如果 ...

  2. win10系统修改Intel VT-x时进入不了BIOS问题

    一般电脑进入BIOS的方式都是在开机的时候不停的按F2或者F12,但是Win10系统由于支持快速启动,当win10系统快速启动的时候,按F12或者F2是没反应的,解决方式: 第一步:修改win10的启 ...

  3. 《Effective MySQL之SQL语句最优化》读书笔记——乱七八糟系列(给自己看)

    该书区别于诸如<MySQL技术内幕——InnoDB存储引擎>等书的一大特色是该书主要讲的是MySQL数据库中的索引技术,并分别讲了InnoDB.MyISAM.Memory三个存储引擎.其中 ...

  4. Linux文件系统管理 parted分区命令

    概述 parted 命令是可以在命令行直接分区和格式化的,不过 parted 交互模式才是更加常用的命令方式. parted命令 进入交互模式命令如下: [root@localhost ~]# par ...

  5. MySQL数据库基本操作(四)

    在进行查询之前,我们要先建好关系表,并往数据表中插入些数据.为查询操作做好准备. 五张关系表的创建: #创建并进入数据库: mysql> CREATE DATABASE `info`; Quer ...

  6. 一览Swift中的常用关键字

    要学习Swift这门语言,就必须先了解Swift的关键字及对应的解释.这里就列一下在Swift中常用到的关键字. 关键字是类似于标识符的保留字符序列,除非用重音符号(`)将其括起来,否则不能用作标识符 ...

  7. Kubernetes Storage

    参考文章: https://kubernetes.io/docs/concepts/storage/volumes/ https://www.cnblogs.com/styshoo/p/6731425 ...

  8. tomcat常见面试题1

    一.Tomcat的缺省是多少,怎么修改 Tomcat的缺省端口号是8080. 修改Tomcat端口号: 1.找到Tomcat目录下的conf文件夹 2.进入conf文件夹里面找到server.xml文 ...

  9. linux下bwa和samtools的安装与使用

    bwa的安装流程安装本软体总共需要完成以下两个软体的安装工作:1) BWA2) Samtools 1.BWA的安装a.下载BWA (download from BWA Source Forge ) h ...

  10. 考勤助手——基于CS三层结构的子系统设计

    因为小组比较倾向于cs分层结构的风格,所以基于对考勤助手最初的体系架构的设计进行了子系统的分层设计,如下图: 1.教务老师安排课程子系统 2.教务老师查询相关信息的子系统 3.任课教师管理考勤子系统 ...