题目https://pintia.cn/problem-sets/994805342720868352/problems/994805343727501312

题意:

给定一个二叉搜索树,以及他的前序遍历序列。

现在有m组询问,对于给定的两个关键字值u,v问他们的最近公共祖先是谁。

思路:

根本跟LCA都没关系好吗。m不是很大,每组询问都查找一次u和v就行了。

因为是BST所以根据前序序列可以直接建出这棵树。

然后在树上查找u和v。

本来还用了一个vector分别存根到u,v的路径,然后两个循环暴力找到最近公共祖先。然后超时了。

其实根本不用这么麻烦,只用在查找的过程中用一个vis数组来标记上一次查找是否已经经过这个点了。如果已经访问过,那么说明这个祖先是他们公共的,更新答案。

因为是从顶开始的遍历所以最后结束时的答案肯定是最近的公共祖先。

 //#include<bits/stdc++>
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<stdlib.h>
#include<queue>
#include<map>
#include<stack>
#include<set> #define LL long long
#define ull unsigned long long
#define inf 0x3f3f3f3f using namespace std; int n, m;
const int maxn = 1e4 + ;
int preorder[maxn]; struct node{
int lchild = -, rchild = -;
int key;
}tree[maxn];
int tot = ; bool Insert(int val, int rt)
{
if(val < tree[rt].key){
if(tree[rt].lchild == -){
tree[tot].key = val;
tree[rt].lchild = tot++;
return true;
}
else return Insert(val, tree[rt].lchild);
}
else if(val > tree[rt].key){
if(tree[rt].rchild == -){
tree[tot].key = val;
tree[rt].rchild = tot++;
return true;
}
else return Insert(val, tree[rt].rchild);
}
else return true;
} //vector<int>path[2];
int vis[maxn], ans;
bool ffind(int val)
{
// path[u].clear();
//memset(vis, 0, sizeof(vis));
int now = ;
while(now != -){
if(tree[now].key == val){
if(vis[now])ans = now;
else vis[now] = true;
// path[u].push_back(now);
return true;
}
else if(val < tree[now].key){
if(vis[now])ans = now;
else vis[now] = true;
// path[u].push_back(now);
now = tree[now].lchild;
}
else if(val > tree[now].key){
if(vis[now])ans = now;
else vis[now] = true;
// path[u].push_back(now);
now = tree[now].rchild;
}
}
if(now == -)return false;
} void printtree(int rt)
{
if(rt == -)return;
printf("%d ", tree[rt].key);
printtree(tree[rt].lchild);
printtree(tree[rt].rchild);
return;
} int main()
{
scanf("%d%d", &m, &n);
tree[].key = inf;
for(int i = ; i < n; i++){
scanf("%d", &preorder[i]);
Insert(preorder[i], );
}
//printtree(1);
while(m--){
int u, v;
scanf("%d%d", &u, &v);
ans = -;
memset(vis, , sizeof(vis));
bool fu = ffind(u);
bool fv = ffind(v);
if(!fu && !fv){
printf("ERROR: %d and %d are not found.\n", u, v);
}
else if(!fu){
printf("ERROR: %d is not found.\n", u);
}
else if(!fv){
printf("ERROR: %d is not found.\n", v);
}
else{
// for(int i = 0; i < path[0].size(); i++)printf("%d ", tree[path[0][i]].key);printf("\n");
// for(int j = 0; j < path[1].size(); j++)printf("%d ", tree[path[1][j]].key);printf("\n"); if(tree[ans].key == u){
printf("%d is an ancestor of %d.\n", u, v);
}
else if(tree[ans].key == v){
printf("%d is an ancestor of %d.\n", v, u);
}
else if(ans != -){
printf("LCA of %d and %d is %d.\n", u, v, tree[ans].key);
}
}
} return ;
}

PAT甲级1143 Lowest Common Ancestor【BST】的更多相关文章

  1. PAT 甲级 1143 Lowest Common Ancestor

    https://pintia.cn/problem-sets/994805342720868352/problems/994805343727501312 The lowest common ance ...

  2. PAT Advanced 1143 Lowest Common Ancestor (30) [二叉查找树 LCA]

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

  3. PAT 1143 Lowest Common Ancestor[难][BST性质]

    1143 Lowest Common Ancestor(30 分) The lowest common ancestor (LCA) of two nodes U and V in a tree is ...

  4. [PAT] 1143 Lowest Common Ancestor(30 分)

    1143 Lowest Common Ancestor(30 分)The lowest common ancestor (LCA) of two nodes U and V in a tree is ...

  5. PAT 1143 Lowest Common Ancestor

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

  6. 1143 Lowest Common Ancestor

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

  7. 1143. Lowest Common Ancestor (30)

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

  8. [PAT] 1143 Lowest Common Ancestor(30 分)1145 Hashing - Average Search Time(25 分)

    1145 Hashing - Average Search Time(25 分)The task of this problem is simple: insert a sequence of dis ...

  9. Lowest Common Ancestor of a Binary Search Tree (BST)

    Given a binary search tree(BST), find the lowest common ancestor of two given nodes in the BST. Node ...

随机推荐

  1. ionic andorid apk 签名, 查看签名MD5

    ionic cordova build android生成的是带签名的android-debug.apk, 这个是可以在手机上安装的, 但是换个电脑打包这个签名就不一样了, 这样就不能直接替换安装了, ...

  2. 解决windows 下 mysql命令行导入备份文件 查询时乱码的问题

    Mysql导入乱码,一般在命令行会遇到.下面说的是命令行的情况下解决乱码问题: 方法一: 通过增加参数 –default-character-set = utf8 解决乱码问题 mysql -uroo ...

  3. 【PHP】解析PHP中的错误和异常处理

    目录结构: contents structure [-] 错误级别 自定义处理器 设置异常日志 自定义异常类 在这篇文章中,笔者将会阐述PHP中的异常处理,希望能够对你有所帮助. 1.错误级别 PHP ...

  4. 16.翻译系列:EF 6 Code -First中使用存储过程【EF 6 Code-First系列】

    原文链接:https://www.entityframeworktutorial.net/entityframework6/code-first-insert-update-delete-stored ...

  5. Atitit s2018.2 s2 doc list on home ntpc.docx  \Atiitt uke制度体系 法律 法规 规章 条例 国王诏书.docx \Atiitt 手写文字识别 讯飞科大 语音云.docx \Atitit 代码托管与虚拟主机.docx \Atitit 企业文化 每日心灵 鸡汤 值班 发布.docx \Atitit 几大研发体系对比 Stage-Gat

    Atitit s2018.2 s2 doc list on home ntpc.docx \Atiitt uke制度体系  法律 法规 规章 条例 国王诏书.docx \Atiitt 手写文字识别   ...

  6. Asp.Net任务Task和线程Thread

    Task是.NET4.0加入的,跟线程池ThreadPool的功能类似,用Task开启新任务时,会从线程池中调用线程,而Thread每次实例化都会创建一个新的线程.任务(Task)是架构在线程之上的, ...

  7. 华为AR配置内部服务器示例(只有1个公网IP)

    AR配置公网和私网用户都可以通过公网地址访问内部服务器示例(只有1个公网IP) 适用于:V200R003C01及以后的系统软件版本. 组网需求: 由于只有1个公网IP(100.100.1.2),想实现 ...

  8. linux下反编译android apk

    1.所需要的工具 1)apktool,功能:反编译出apk所需要的资源文件和布局设置文件等, 下载地址:https://code.google.com/p/android-apktool/downlo ...

  9. 【ML入门系列】(二)分类与回归

    前言 在机器学习中,“分类”和“回归”这两个词经常听说,但很多时候我们却混为一谈.本文主要从应用场景.训练算法等几个方面来叙述两者的区别. 本质区别 分类和回归的区别在于输出变量的类型.分类的输出是离 ...

  10. 31Spring的一些想法

    看一遍以前的自己写的博客,记录下自己的一些想法,Spring分为两块:IOC和AOP.IOC就是在applicatcontext.xml中配置<<bean......>>这种. ...