爆刷PAT(甲级)——之【1151】 LCA in a Binary Tree (30 分)——先序中序建树+LCA问题

关于PAT 1151 LCA in a Binary Tree 最后两个测试点超时的问题优化 关于PAT 1151 LCA in a Binary Tree 最后两个测试点超时的问题的优化 题目链接:https://pintia.cn/problem-sets/994805342720868352/problems/1038430130011897856 he 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. Giv 阅读详情

此题也是去年考的时候不会。时隔一年才来补一下。

这题网上其实很多的讲解了。大概分成三种讲法流派,一种是以柳神为代表的非建树递归找父子关系派;一类是最通俗常规的建树+遍历递归找LCA方法派;还有一类是只贴代码没有讲解或是使用了RMQ倍增高级方法解决LCA问题等。

记此博客来简单的缕一缕自己的LCA思绪。

脑袋已经锈了很久了。

 

1、先谈一下,最常规的建树+递归遍历LCA方法,本题复杂度就是O(2MN+MN):

题意;给一个二叉树(并不是BST)的先序遍历和中序遍历,节点值不重复。然后给M个值对的查询,求它们的最近公共祖先LCA节点。

难点:一个数输出的时候要分成好几个情况,写起来比较蛋疼。

还有一个,先不谈是不是必要进行建树,我们姑且就要建树的话,如何写出先序遍历/后序遍历 + 中序遍历进行建树。这个不去看一下以及多写几遍,是会导致大悲剧的。很重要!

第三个是,在判断完毕待查校训数据是否存在有效之后,如何进行常规的LCA递归遍历二叉树去寻找最近共同祖先呢?思路是——LCA的共同祖先分成三种情况:A和B不在同一颗子树,那么A和B的共同“根爷爷”就是答案;A在B的下侧,那么B就是A的祖先(在一侧);反之亦然,B在A的下侧(同侧),那么A就是B的祖先。——如此以来,我们从根节点开始递归左子树以及右子树分别去找A或者B,如果先找到了A,那不就说明B在A的下面几层(所以才A找到的时候B还没找到);如果先找到了B而A没找到,那A就是祖先;如果在左右子树分别找到A和B,那就说明当前节点就是它们的“共同根祖先”。

 

详细看代码吧

Code:

#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;
#define inf 10009
#define INF 0x3f3f3f3f
int n,m;
int preorder[inf],inorder[inf];
struct Node
{
    Node *left,*right;
    int value;
    Node(int v)
    {
        value=v;
        left=right=NULL;
    }
};
int flag;//结果类型
Node* Preorder_Inorder_Create(int l1,int r1,int l2,int r2)//先序中序遍历建树
{
    if(l2>r2)return NULL;
    Node *root=new Node(preorder[l1]);
    int i;
    for(i=l2;inorder[i]!=preorder[l1];i++);
    int len=i-l2;
    root->left=Preorder_Inorder_Create(l1+1,l1+len,l2,i-1);
    root->right=Preorder_Inorder_Create(l1+1+len,r1,i+1,r2);
    return root;
}
Node* findFather(Node *root,int a,int b)//递归找公共祖先
{
    if(!root)return NULL;
    else if(root->value==a||root->value==b)return root;

    Node *left=findFather(root->left,a,b);
    Node *right=findFather(root->right,a,b);
    if(left&&right){return root;}//左右子树
    else if(!left)return right;//在一边——右边
    else return left;//在一边——左边
}
int main()
{
    int i,j,k;
    cin>>m>>n;
    for(i=0;i<n;i++)cin>>inorder[i];
    for(i=0;i<n;i++)cin>>preorder[i];
    Node *root=Preorder_Inorder_Create(0,n-1,0,n-1);
    while(m--)
    {
        int a,b;
        cin>>a>>b;

        //判断数是否存在
        for(i=0;i<n;i++)if(preorder[i]==a)break;
        for(j=0;j<n;j++)if(preorder[j]==b)break;
        bool exsit1=(i==n)?1:0;
        bool exsit2=(j==n)?1:0;
        if(exsit1&&exsit2){printf("ERROR: %d and %d are not found.\n",a,b);continue;}//都不在
        else if(exsit1||exsit2){printf("ERROR: %d is not found.\n",exsit1?a:b);continue;}//某一个不在

        Node *ans=findFather(root,a,b);
        int value=ans->value;
        if(value==a)printf("%d is an ancestor of %d.\n",a,b);
        else if(value==b)printf("%d is an ancestor of %d.\n",b,a);
        else printf("LCA of %d and %d is %d.\n",a,b,value);
    }

    return 0;
}

 

Apollo学习笔记(4)坐标系 百度Apollo项目用到了多种坐标系,其中帮助文档提及的坐标系包括: 全球地理坐标系(The Global Geographic coordinate system ) 局部坐标系—东-北-天坐标(The Local Frame – East-North-Up,ENU) 车身坐标系—右-前-天坐标(The Vehicle Frame —Right-Forward-Up,RFU) 车身坐标系—前-左-天坐标(The Vehicle Frame —Front-Left-Up,FLU) 还有一种Frenet坐标 阅读详情

相关推荐

Carla-UE4Editor导入RoadRunner地图文件(保姆级教程)

以Carla官网导入RoadRunner地图的标准文档为参考,里面增添了很多细节和注意事项,遇到问题的小伙伴过来看看吧。

DSK_981029的博客 1万+

1151 LCA in a Binary Tree(30 分)

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 and V as descendants. Given any two nodes in a binary tree, you ar...

L_Aster的专栏 1011

实例讲解MOS管电源开关电路的软启动

1、控制电源开关的输入信号 Control 为低电平或高阻时,三极管Q2的基极被拉低到地,为低电平,Q2不导通,进而MOS管Q1的Vgs = 0,MOS管Q1不导通,+5V_OUT 无输出。此时将 Control 设为低电平,三极管Q2关闭,电容C1与G极相连端通过电阻R2放电,电压逐渐上升到5V,起到软关闭的效果。不过从作者的描述来看,只是电路参数有区别,能通过的电流、能承受的耐压等不一样,但是软启动的原理是一样的。从公式可以看出,当电容容量越大,电压越高,时间越短,电流就会越大,从而形成浪涌电流。

U_YAO的博客 2万+

1151 LCA in a Binary Tree (30 分)

LZ做题太少,一开始只想到建树、然后分别找到两个元素所在的分支序列、然后找到第一个公共元素这种方法,提交之后得到22分,最后两个测试点超时;后来参考大佬https://blog.youkuaiyun.com/qq_41317652/article/details/82557975的方法,原来lca只需要一次遍历就ok了,不需要找两个序列,下面附上我的22分代码(第2段代码)和AC代码(第1段代码); #i...

csg3140100993的博客 494

Ecg信号QRS波峰检测:A Real-Time QRS Detection Algorithm (Pan-Tompkins法)

Pan-Tompkins法是R峰检测的经典方法,被引量高达6000+次。 Pan J, Tompkins W J. A real-time QRS detection algorithm[J]. IEEE transactions on biomedical engineering, 1985 (3): 230-236. 本文对论文流程进行了总结,并参考BioSigKit项目,复现了论文代码。 流程图: 代码如下: 第一部分是信号读入,这里使用MIT_BIH信号的100,读入10000个数据点 第二部分

weixin_42870380的博客 1万+

嵌入式开源项目哪里找

对比产生的伤害是经验思考积累下的差距,知道自己不知道什么然后前进去追寻。

quanquanxiaobu的博客 3938

lca学习心得

lca求树上两点最近的公共祖先。 对于树上两点最近的公共祖先,我们首先能想到的办法,就是暴力,如果深度不相同先调整到相同深度,如果深度相等了,祖先不同的话,就继续向上找,直到找到相同的公共祖先。 但是这样的方法,显然速度太慢,那么我们该怎么寻找两个点最近的公共祖先呢? 我们可以处理一颗树上的所有点将其所有的2的次幂的祖先处理出来,放在一个数组中,寻找两个点共同公共祖先时,首先将两个点深度调到...

Black__wing的博客 413

瑞萨单片机,把CS文件转换为CC

1、打开CC的软件: 点击坐上角的"START" 点击"Create New Project"的"GO": 导入工程: 如下图设置后,点击"Create" 2、进入到CC的开发界面: 可以看到原启动库文件以asm文件的方式直接出现在工程中: 删除新生成的main.c,保留导入的r_main.c(以你自己的代码为准): 注意添加所有的头文件路径: 点击"...

weixin_37611121的博客 1228

1151 LCA in a Binary Tree (30 分)(C++)

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

qq_41562704的博客 557

Autosar诊断实战系列05-Dcm之0x27加解密服务配置开发详解

UDS 0x27服务实战开发介绍,对解锁尝试次数及delay时间进一步解释。

initiallizer的博客 1991

YOLO-World:从入门到实战的多模态目标检测全指南

想象一下,你给模型一张“公园”的图片,再输入文字“红色的郁金香”,它能直接在图中框出所有红色郁金香的位置——这就是多模态目标检测:结合图像视觉信息和文本语义信息,同时完成“是什么”(分类)和“在哪里”(定位)的任务。传统目标检测(如YOLOv5、YOLOv8)只能识别预定义的类别(比如训练时学过“猫”“狗”),但多模态目标检测摆脱了“类别预定义”的限制,只要文本能描述,它就能检测,这就是“开放词汇检测(Open-Vocabulary Detection)”的魅力。

know_F0727的博客 204

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 both U and V as descendants. Given any two nodes in a binary tree, you are supposed to find their LCA. In...

柳婼 の blog 9113

“华为杯”研究生数学建模竞赛2020年-【华为杯】B题:汽油辛烷值优化建模(附优秀论文)

摘 要:本文通过机器学习算法和数据挖掘技术,建立了汽油辛烷值(RON)损失的预测模型,在保证汽油产品脱硫效果的前提下,以降低汽油辛烷值损失在30%以上为目标,给出每个样本的优化操作条件。针对第一问,对285号和313号原始数据用给定的数据处理规范进行预处理,对每一列变量求期望,得到最终的数据补充到相应的样本编号。针对第二问,首先对数据样本按照最大最小限幅以及拉依达法则进行列变量清洗,通过两轮特征筛选确定变量:结合处理后的数据,针对产品中硫含量、RON损失值用。

getusushu的博客 1251

PAT 甲级 1151  LCA in a Binary Tree

1151LCA in a Binary Tree(30 point(s)) 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...

漫浸天空的雨色的备忘录~ 946

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

PAT甲级 1151 LCA in a Binary Tree (30分) 最近公共祖先

PAT甲级 1151 LCA in a Binary Tree (30分) 最近公共祖先 题目大意: 给出中序序列和先序序列,再给出两个点,求这两个点的最近公共祖先 不建树的做法: 已知某个树的根结点,若a和b在根结点的左边,则a和b的最近公共祖先在当前子树根结点的左子树寻找,如果a和b在当前子树根结点的两边,在当前子树的根结点就是a和b的最近公共祖先,如果a和b在当前子树根结点的右边,则a和...

化身孤岛的鲸o的博客 643

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

18年秋季第四题 PAT甲级 1151 LCA in a Binary Tree (30分)

题目来源:https://pintia.cn/problem-sets/994805342720868352/problems/1038430130011897856 备考汇总贴:2020年3月PAT甲级满分必备刷题技巧 题目 The lowest common ancestor (LCA) of two nodes U and V in a tree is the deepest node...

qiiingc的解题记录 1098

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

pat甲级1151 LCA in a Binary Tree (30分)

pat甲级1151 LCA in a Binary Tree (30分) #include <iostream> #include <unordered_map> #include <vector> using namespace std; vector<int> in,pre; unordered_map<int,int> pos;//不可以直接开数组pos[10005],因为整数内含有负数,无需排序,因此用unordered_map //各分

qq_44992782的博客 319

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

给定先序中序遍历的序列,可以确定一颗唯一的树 先序遍历第一个遍历到的是根,中序遍历确定左右子树 查结点a和结点b的最近公共祖先,简单lca思路: 1.如果a和b分别在当前根的左右子树,当前的根就是最近祖先 2.如果根等于a或者根等于b了,根就是最近祖先;判断和a等还是和b等就行了 3.如果都在左子树上,递归查左子树就可以了。这里找到左子树的边界和根(通过先序中序序列) 4.如果都在右子树上,递归查...

weixin_30606669的博客 180

PAT 甲级 1151 LCA in a Binary Tree (30 分)

PAT 甲级 1151 LCA in a Binary Tree思路:代码: 太惭愧了,这题暴力解的,玩不来各个大佬的lca算法。 思路: 1.将中根先根序列存储,然后用递归分治分别求出每个key的父结点,同时记录结点层次; 2.用全局变量存储中根先根序列,然后以下标范围来限定子树范围,我之前在每次递归时又定义两个vector来复制树的一个区间,以起到遍历子树的效果,结果后三个内存超了; 3.对于...

Yuhan的博客 239

PAT甲级1151 LCA in a Binary Tree LCA+DFS

LCA问题在常规树中的实现,思路和1143一样,本体主要要解决的就是递归子树边界的问题 我采用的map映射的方法,将中序遍历的结点值映射为下标位置,那么如果用下标来代替结点值的话,当前的树便是一颗bst树了 利用这个特性,比较映射值便可以判断左右子树的关系 #include<iostream> #include<vector> #include<unordered_map> #include<cstdio> using namespace std...

Artorias的博客 2831

1151 LCA in a Binary Tree (30 分)--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 both U and V as descendants. Given any two nodes in a binary tree, you are...

laplacebh的博客 621

PAT 1151 LCA in a Binary Tree

原题链接:1151 LCA in a Binary Tree (30分) 关键词:LCA

cwtnice的博客 241

PAT 甲级 1151 LCA in a Binary Tree (30 分) 先序中序遍历求LCA

题意: 给定一棵二叉树,求两个点的LCA(最近公共祖先) 思路: 大赞柳姐姐的博文,一眼就看到了这种求LCA的方法! 聪明 机智 温柔 活泼 可爱 伶俐 宇宙超级无敌萌萌哒 天才少女小柳柳~~~ 爱了爱了 这个方法就是根据先序遍历中序遍历建树的过程,如果两个结点在当前树的根节点的两测,那他们的LCA就是当前结点; 如果当前树的根节点就是两个结点中的一个,那当前结点就是另一个的祖先 ...

床前明月光 230

【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 both U and V as descendants.Given any two nodes in a binary tree, you are supposed to find their ...

denghong637573的博客 187

PAT甲级1151 LCA in a Binary Tree (30 分)

1151LCA 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 and V as descendants. Given any two nodes in a binary tree, you a...

Dexter 300

PAT甲级刷题之路——A1151 1151 LCA in a Binary Tree

PAT A1151 1151 LCA in a Binary Tree(30分)原题如下题目大意自己的想法错误总结错误1错误2AC代码结语 原题如下 题目大意 找出两个键值的最近共同祖先 自己的想法 一开始我打算先建树再遍历,后来发现不用建树直接遍历就行。 错误总结 错误1 就是已知中序、先序求后序的过程中经常犯的错误 post(prel + 1, prel + sum, inl, k - 1...

qq_43677396的博客 526
上一篇: 爆刷PAT(甲级)——之【1148】 Werewolf - Simple Version(20 分)——思维
下一篇: 爆刷PAT(甲级)——之【1153】 Decode Registration Card of PAT (25 分)——模拟细节题(如何解决超时问题!)
仰天倀笑
博客等级 码龄10年 313粉丝 124原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值