最近公共祖先LCA的几种解决方案
来源:互联网 发布:阿里云 不同可用区互通 编辑:程序博客网 时间:2024/06/06 00:54
问题是,已经知道一棵二叉树的根结点root和其中的两个结点p1和p2,求p1与p2的最近公共祖先
有几种不同的方法:
方法一,
给每个结点记数,除了p1和p2指向的结点记为1外,其余结点的均记为0
然后采用后序遍历的方法,依次计算每个结点其左结点和右结点的和,第一个发现的和为2的结点,即所求结点,如果和不为2,则更新当前结点的值,直到找到一个结点和为2为止。
方法二,
我们来看这样一棵二叉树
(1)
/ /
(2) (7)
/ / /
(3) (4) (8)
/ /
(5) (6)
我们按照某种规律来遍历整棵树,得到结点访问顺序为
1 2 3 2 4 5 4 6 4 2 1 7 8 7 1
其对应的结点深度为
0 1 2 1 2 3 2 3 2 1 0 1 2 1 0
比如我们来查询结点3和结点6的最近公共祖先,考虑在访问顺序中结点3和结点6第一次出现之间的序列
3 2 4 5 4 6,这是由结点3到结点6之间的一条路径
在这条路径中,深度最小的结点就是所求的最近公共祖先,即结点2
于是问题转化为,给定一个数组,及两个位置i和j,如何找出数组R中从位置i到位置j的最小值
这个问题就是典型的RMQ问题
RMQ问题有一个简单的方法来解决,但需要先进行一下预处理
用一个数组d[i][j]表示数组R中,[ i, i + 2 ^ j - 1 ]这段区间中的最小值
这个d[i][j]很容易得到,因为有方程
d[ i ][ j + 1 ] = min { d[i][ j ], d[ i + 2 ^ j ][ j ] }
预处理的空间复杂度是O(nlogn),时间复杂度也是O(nlogn)
如果询问从a到b里的最小值,思路是找两个长度为2^k的区间,即
[ a, a + 2 ^ k - 1 ]及[ b - 1 - 2 ^ k, b ]把区间[a, b]覆盖掉
只要 2 ^ ( k + 1 ) >= | b - a |
就能找到这个k
所以区间[a,b]中的最小值是 min{ d[ a ][ k ], d[ b - 2 ^ k - 1 ][ k ] }
- 最近公共祖先LCA的几种解决方案
- 最近公共祖先LCA
- 最近公共祖先(LCA)
- Lca 最近公共祖先
- LCA----最近公共祖先
- LCA (最近公共祖先)
- LCA最近公共祖先
- LCA 最近公共祖先
- 最近公共祖先 LCA
- LCA--最近公共祖先
- LCA(最近公共祖先)
- LCA最近公共祖先
- LCA(最近公共祖先)
- LCA 最近公共祖先
- 最近公共祖先LCA
- LCA 最近公共祖先
- 【LCA】最近公共祖先
- LCA最近公共祖先
- 嵌入式软件开发---总结篇
- android学习三 手机页面的转换
- 常用FTP命令及简单上传下载实例大搜捕2
- 常用FTP命令及简单上传下载实例大搜捕2
- 如何设置到映射网络驱动器的超时连接时间
- 最近公共祖先LCA的几种解决方案
- Browse the Linux Kernel Source with LXR
- 常用FTP命令及简单上传下载实例大搜捕3
- 利用thrift API访问Cassandra 第二天
- ASP.NET绘制条形图
- C#连接接MySQL
- js日期在火狐显示为111年的问题
- Nutch的一些分析
- 内核编译篇-------