PAT (Advanced Level) Practice - 1151 LCA in a Binary Tree(30 分)

简介: PAT (Advanced Level) Practice - 1151 LCA in a Binary Tree(30 分)

题目链接:点击打开链接

题目大意:给出中序序列和先序序列,再给出两个点,求这两个点的最近公共祖先。

解题思路:不用建树~已知某个树的根结点,若a和b在根结点的左边,则a和b的最近公共祖先在当前子树根结点的左子树寻找,如果a和b在当前子树根结点的两边,在当前子树的根结点就是a和b的最近公共祖先,如果a和b在当前子树根结点的右边,则a和b的最近公共祖先就在当前子树的右子树寻找。中序加先序可以唯一确定一棵树,在不构建树的情况下,在每一层的递归中,可以得到树的根结点,在此时并入lca算法可以确定两个结点的公共祖先~

注意:题目中 n 才是结点个数;pos 不能用数组开,因为存储位置的是利用该结点的值而不是下标,所以用ump。

AC 代码1(未建树版)

#include<bits/stdc++.h>#include<cmath>#define mem(a,b) memset(a,b,sizeof a)#define ssclr(ss) ss.clear(), ss.str("")#define INF 0x3f3f3f3f#define MOD 1000000007usingnamespacestd;
typedeflonglongll;
constintmaxn=1e4+10;
intin[maxn], pre[maxn];
unordered_map<int,int>pos;
voidlca(intinl,intinr,intprel,inta,intb)
{
if(inl>inr) return;
intinRt=pos[pre[prel]], aIn=pos[a], bIn=pos[b];
if(inRt>aIn&&inRt<bIn||inRt<aIn&&inRt>bIn) printf("LCA of %d and %d is %d.\n", a, b, in[inRt]);
elseif(aIn==inRt||bIn==inRt) printf("%d is an ancestor of %d.\n", in[inRt], aIn==inRt?b : a);
elseif(aIn>inRt&&bIn>inRt) lca(inRt+1,inr,prel+1+(inRt-inl),a,b);
elseif(aIn<inRt&&bIn<inRt) lca(inl,inRt-1,prel+1,a,b);
}
intmain()
{
intq,n,a,b;
scanf("%d%d",&q,&n);
for(inti=1;i<=n;i++) scanf("%d",&in[i]), pos[in[i]]=i;
for(inti=1;i<=n;i++) scanf("%d",&pre[i]);
while(q--)
    {
scanf("%d%d",&a,&b);
if(pos[a]==0&&pos[b]==0) printf("ERROR: %d and %d are not found.\n", a, b);
elseif(pos[a]==0||pos[b]==0) printf("ERROR: %d is not found.\n", pos[a] ==0?a : b);
elselca(1,n,1,a,b);
    }
return0;
}

AC 代码2(建树-搜索版)

#include<bits/stdc++.h>#include<cmath>#define mem(a,b) memset(a,b,sizeof a)#define ssclr(ss) ss.clear(), ss.str("")#define INF 0x3f3f3f3f#define MOD 1000000007usingnamespacestd;
typedeflonglongll;
constintmaxn=1e4+10;
structnode{
intd,l,r;
}T[maxn];
unordered_map<int,int>vis;
intin[maxn], pre[maxn];
intcreate(intl1,intr1,intl2,intr2) // in pre{
if(l1>r1) return-1;
intrt=l2;
intp1=l1,p2;
while(in[p1]!=pre[rt]) p1++;
p2=p1-l1;
T[rt].d=pre[rt];
T[rt].l=create(l1,p1-1,l2+1,l2+p2);
T[rt].r=create(p1+1,r1,l2+p2+1,r2);
returnrt;
}
intlca(intrt,inta,intb)
{
if(rt==-1) return-1;
if(a==T[rt].d||b==T[rt].d) returnrt;
intleft=lca(T[rt].l,a,b);
intright=lca(T[rt].r,a,b);
if(left!=-1&&right!=-1) returnrt;
returnleft==-1?right : left;
}
intmain()
{
intn,q,a,b;
scanf("%d%d",&q,&n);
for(inti=0;i<n;i++) scanf("%d",&in[i]), vis[in[i]]=1;
for(inti=0;i<n;i++) scanf("%d",&pre[i]);
intrt=create(0,n-1,0,n-1);
while(q--)
    {
scanf("%d%d",&a,&b);
if(!vis[a] &&!vis[b]) printf("ERROR: %d and %d are not found.\n",a,b);
elseif(!vis[a] ||!vis[b]) printf("ERROR: %d is not found.\n",!vis[a]?a:b);
else        {
intminRt=lca(rt,a,b);
if(T[minRt].d==a||T[minRt].d==b) printf("%d is an ancestor of %d.\n",T[minRt].d,T[minRt].d==a?b:a);
elseprintf("LCA of %d and %d is %d.\n",a,b,T[minRt].d);
        }
    }
return0;
}

AC 代码3(建树-LCA版)

#include<bits/stdc++.h>#include<cmath>#define mem(a,b) memset(a,b,sizeof a)#define ssclr(ss) ss.clear(), ss.str("")#define INF 0x3f3f3f3f#define MOD 1000000007usingnamespacestd;
typedeflonglongll;
constintmaxn=1e4+10;
structnode{
intd,l,r;
}T[maxn];
unordered_map<int,int>vis, lvl, fu;
intin[maxn], pre[maxn];
intcreate(intl1,intr1,intl2,intr2,intl,intf) // in pre{
if(l1>r1) return-1;
intrt=l2;
intp1=l1,p2;
while(in[p1]!=pre[rt]) p1++;
p2=p1-l1;
T[rt].d=pre[rt];
lvl[pre[rt]]=l;
fu[pre[rt]]=f;
T[rt].l=create(l1,p1-1,l2+1,l2+p2,l+1,pre[rt]);
T[rt].r=create(p1+1,r1,l2+p2+1,r2,l+1,pre[rt]);
returnrt;
}
intlca(inta,intb)
{
introot;
if(a==b) returna;
if(fu[a]==fu[b]) returnfu[a];
if(lvl[a]>lvl[b]) root=lca(fu[a],b);
elseroot=lca(a,fu[b]);
if(root!=-1) returnroot;
return-1;
}
intmain()
{
intn,q,a,b;
scanf("%d%d",&q,&n);
for(inti=0;i<n;i++) scanf("%d",&in[i]), vis[in[i]]=1;
for(inti=0;i<n;i++) scanf("%d",&pre[i]);
intrt=create(0,n-1,0,n-1,1,-1);
while(q--)
    {
scanf("%d%d",&a,&b);
if(!vis[a] &&!vis[b]) printf("ERROR: %d and %d are not found.\n",a,b);
elseif(!vis[a] ||!vis[b]) printf("ERROR: %d is not found.\n",!vis[a]?a:b);
else        {
intminRt=lca(a,b);
if(minRt==a||minRt==b) printf("%d is an ancestor of %d.\n",minRt,minRt==a?b:a);
elseprintf("LCA of %d and %d is %d.\n",a,b,minRt);
        }
    }
return0;
}
目录
相关文章
Fastadmin后台页面添加顶部按钮
操作的前提是需要在fastadmin框架中添加对应的控制器、模型、视图页面,可以手动创建,也可以使用curd一键生成。
559 0
|
JSON 文字识别 API
ocr表格识别返回的json结果,转成excel,这个转化有对应的逻辑代码吗?
ocr表格识别返回的json结果,转成excel,这个转化有对应的逻辑代码吗?
889 0
|
11月前
|
存储 NoSQL MongoDB
Redis在中国火爆,为何MongoDB更受欢迎国外?
本文介绍了Redis和MongoDB的基本概念及其在GitHub Star、DB-Engines Ranking和Google Trends中的数据对比。Redis是一个基于内存的键值对存储数据库,适合快速读写场景;MongoDB则是面向文档的数据库,支持大规模数据存储和复杂查询。全球范围内,MongoDB的搜索热度高于Redis,但在中国市场,Redis更受欢迎,因其高性能和低延迟特性满足了中国互联网公司对高并发的需求。总结部分分析了两者的特点及适用场景,并结合中美两国的行业背景解释了其受欢迎程度的不同原因。
365 1
|
12月前
|
搜索推荐 开发工具
Vim编辑器的初步认识和使用
Vim是一款高度可定制的文本编辑器,支持三种主要模式:正常模式、编辑模式和命令行模式。用户可以通过快捷键在不同模式间切换,实现高效编辑。如输入`i`进入编辑模式,`:wq`保存退出,`:s`进行文本替换等。Vim还支持个性化配置,通过编辑`.vimrc`文件可设置语法高亮、自动缩进等功能,极大提升了编辑体验。
185 2
|
XML JSON Ubuntu
Python实用记录(十五):PyQt/PySide6打包成exe,精简版(nuitka/pyinstaller/auto-py-to-exe)
本文介绍了使用Nuitka、PyInstaller和auto-py-to-exe三种工具将Python的PyQt/PySide6应用打包成exe文件的方法。提供了详细的安装步骤、打包命令和参数说明,适合新手学习和实践。
4334 0
键盘绑定按下事件
键盘绑定按下事件
110 0
|
机器学习/深度学习 算法 数据挖掘
使用NumPy实现经典算法案例集
【4月更文挑战第17天】本文展示了NumPy在Python中实现经典算法的案例,包括使用NumPy进行冒泡排序、计算欧几里得距离、矩阵转置和协方差矩阵。这些示例突显了NumPy在数值计算、数据分析和科学计算中的威力,强调了掌握NumPy对于数据科学家和机器学习开发者的重要性。
|
运维 Cloud Native 关系型数据库
活动回顾|阿里云 Serverless 技术实战与创新成都站回放&PPT下载
7月29日“阿里云 Serverless 技术实战与创新”成都站圆满落幕。可免费下载成都站|阿里云 Serverless 沙龙演讲 PPT。
|
存储 编译器 程序员
c++【继承】
C++ 继承,包括继承的概念和用法,菱形继承的产生,组合的介绍等丰富知识点,详细讲解,干货满满!
149 4
c++【继承】