查找树的LCA(Least Common Ancestor)算法
前言
Euler Tour of A Tree
ETT即Euler-Tour-Tree,也就是采用欧拉序来访问一棵有n个node的树,例如上图所示的这棵树,欧拉序为:9 2 1 7 1 8 1 2 4 2 6 2 9 3 9 5 9;即从根节点开始,dfs(深度优先遍历,前序遍历)依次输出访问边对应的节点,Euler Tour的长度是2n-1,因为每次遍历一条边时输出一个节点,遍历了n-1条边两次,每个方向一次。这样的好处是,可以通过欧拉序列知道所有子树的信息,比如以1为根节点的子树就包括 (1 7 1 8 1),1、7和8这3个节点;还可以快速得到根节点:(7 1 8)序列中层数最浅的是1,说明1为该子树的根节点。
RMQ(Range Minimum Query)
RMQ范围最小值查找就是给定一个数组,找到该范围内最小元素的索引。LCA问题可以规约为RMQ问题。
LCA
Naive Algorithm
(1)用数组来按顺序存储Euler Tour访问的节点;
(2)用数组存储对应节点的高度(即节点到根节点的距离);
(3)用数组存储每个节点在Euler Tour中第一次出现的索引,即;
(4)两个节点第一次出现之间访问的节点为或者,在这个子序列中最浅的节点即高度最小的就是的LCA,即。
该方法预处理阶段的时间复杂度为,差不多是暴力解法。
Faster RMQ Algorithm
思想——用一个二维表来提前将RMQ的最小值计算并进行存储。
(1)对于每一个和,找到区块的最小的元素并存储在中,即,表的大小为。
(2)使用dynamic programming(DP思想)填满只需要的时间复杂度:对于大小的block,只需计算其两个连续子block的最小值,即。
(3)即使用Sparse Table(ST)来计算RMQ,并需要类似找the most significant bit of a word的操作。
(4)查询:我们需要两个已知的固定区间,能够覆盖(可以重合一部分)整个查询区间。为了方便查找,我们规定这两个已知区间覆盖的区间长度均为2^k,并且两个区间分别有一端为L和R。那么随着这个k不断增大,一定存在一个临界点k,刚好覆盖(或最少重合)这个区间。当k满足题意时,两个区间分别为[L,L+2k−1][L,L+2k−1]和[R−(2k−1),R][R−(2k−1),R],此时只需要满足R−(2k−1)≤L+2k−1R−(2k−1)≤L+2k−1即可,化简之后推出公式:R−L+2≤2k+1,k≥log2(R−L+2)−1。
Fast Algorithm for
思想——基于限制,使用查表方法提前计算小数组的答案,来消除log。指任何邻接的两个节点间的高度差为1或-1.
(1)将数组A按每个block大小为进行划分,得到;
(2)定义一个等大的数组B,表示第个block里最小元素出现的位置;
(3)查询:当查询的起点和不在一个block里时,1)找到从到所在的block里最后一个元素的最小值;2)查找和之间所有block的最小值;3)查找从所在block起始位置到的最小值。
(4)in-block查询优化:对于(3)中的2)的值可以使用ST表实现常数时间复杂度的查询,因此现在主要是优化1)和3)的in-block查询。使用Normalized Block,即依次处理每个block中元素将其将去最初的每个元素,那么对于长度为的block,共由种不同的Normalized Blocks。其余相同的Normalzed Block可以使用相同的预处理,这大大提高了预处理时间。
(5)创建个table,每个table对应一种Normalized Block。每个Block中保存种查询结果。
[References]:
M. A. Bender and M. Farach-Colton. The lca problem revisited. In Proc. of LASTI’00, pages 88–94, 2000.
https://blog.csdn.net/Kanosword/article/details/52659924
https://github.com/leifwalsh/rmq
查找树的LCA(Least Common Ancestor)算法相关推荐
- 语言非递归求解树的高度_算法素颜(11):无死角“盘”它!二分查找树
引言 <菜鸟也能"种"好二叉树!>一文中提到了:为了方便查找,需要进行分层分类整理.而满足这种目标的数据结构之一就是树. 树的叶子节点可以看作是最终要搜寻的目标物:叶子 ...
- 浅谈LCA的几种算法
LCA,Lowest Common Ancestor,最近的公共祖先.在一棵树中对于两个节点u , v找出节点T,使得T同时为u,v的祖先.显然这样的T点肯定存在且有可能有多个,其中深度最大的那个点肯 ...
- PAT A1143 Lowest Common Ancestor ——沉舟侧畔千帆过,病树前头万木春
PAT A1143 Lowest Common Ancestor 第一次遇到LCA,想的比较乱,感觉有点并查集的意思,又好像不行.开始的想法是用BST的性质和前序建树,建树过程中做一个father数组 ...
- PAT甲级1143 Lowest Common Ancestor (30 分):[C++题解]LCA、最低公共祖先
文章目录 题目分析 题目链接 题目分析 来源:acwing 分析:二叉搜索树的中序遍历是隐含给定的,它的中序遍历就是从小到大排列. 所以这道题先是根据给定的前序遍历和中序遍历,建树. 建树的时候需要用 ...
- 【题解】【PAT甲】1143 Lowest Common Ancestor (30 分)(树)(BST)(最近公共祖先)
题目链接 PTA | 程序设计类实验辅助教学平台 题目描述 The lowest common ancestor (LCA) of two nodes U and V in a tree is the ...
- 笔试算法题(58):二分查找树性能分析(Binary Search Tree Performance Analysis)
议题:二分查找树性能分析(Binary Search Tree Performance Analysis) 分析: 二叉搜索树(Binary Search Tree,BST)是一颗典型的二叉树,同时任 ...
- Algorithm:C++语言实现之SimHash和倒排索引算法相关(抽屉原理、倒排索、建立查找树、处理Hash冲突、Hash查找)
Algorithm:C++语言实现之SimHash和倒排索引算法相关(抽屉原理.倒排索.建立查找树.处理Hash冲突.Hash查找) 目录 一.SimHash算法 1.SimHash算法五个步骤 2. ...
- C++lowest common ancestor最近公共祖先算法(附完整源码)
C++lowest common ancestor最近公共祖先算法 C++lowest common ancestor最近公共祖先算法完整源码(定义,实现,main函数测试) C++lowest co ...
- java单词查找树_Trie 单词查找树 java实现(来自算法第4版)
强烈建议看书上的实现步骤,这里只是一个个人记录. 单词查找树的性能: 查找命中所需的时间与被查找的键的长度成正比.比如单词有7个字符,查找或插入操作最多只需要检查8个节点. 查找未命中只需检查若干个字 ...
最新文章
- 吴恩达机器学习笔记-梯度下降
- 知乎用户和龙鹏-言有三:计算机视觉应该怎样入门?
- MySql中如果某一列中含有NULL,那么包含该列的索引就无效了?
- 【Windows】创建任务计划
- 常用 ORACLE 函数的解读
- powershell 发邮件
- 编程语言python入门-2020年10月编程语言:Java、Python 龙争虎斗
- 逻辑回归与梯度下降法
- 学习笔记——正则匹配方法整理
- 计算机办公自动化应用课程,1-《计算机应用基础(办公自动化)》课程标准.doc
- android自定义图标下载,Android使用IconFont矢量图标库
- 【MM32F5270开发板试用】一、移植 TencentOS 到 PLUS-F5270
- python的中介效应 调节效应
- chrome+链接android手机,为什么android手机限制chrome浏览器数据连接还可以上网
- java抽象和接口的理解_Java学习笔记16---抽象类与接口的浅显理解
- 电信催费打错话费单 男子“拖欠”45036亿元话费
- 聚观早报 | 元旦机票预订量增长145%;小米集团副总裁崔宝秋离职
- CornerNet详解
- 微信小程序授权登录(获取手机号及用户信息)
- ROS2——topic话题(八)