LCA(最近公共祖先)(2.14)

定义:LCA,即最近公共祖先,是指在在有根树中,找到两个节点的最近公共祖先。

如图,4和7的最近公共祖先是2。

如何求最近公共祖先:

1:两点同时网上走并标记,若第一次一个点走到被标记过得点,那个点就是最近公共祖先;

2:深度高的点先往上走,直到两点深度一样就一起往上走。

代码:

3.倍增法:

注意到uv走到最近公共祖先w之前,uv所在结点不相同。而到达最近公共祖先w后,再往上走仍是uv的公共祖先,即uv走到同一个结点,这具有二分性质。于是可以预处理出一个2k的表,fa[k][u]表示u往上走2k步走到的结点,令根结点深度为0,则2k>depth[u]时,令fa[k][u]=-1(不合法情况的处理)。不妨假设depth[u] < depth[v]①将v往上走d = depth[v] - depth[u]步,此时uv所在结点深度相同,该过程可用二进制优化。由于d是确定值,将d看成2的次方的和值d = 2k1 + 2k2 + ... + 2km,利用fa数组如v = fa[k1][v]v = fa[k2][v]加速。

②若此时u = v,说明Lca(u,v)已找到

③利用fa数组加速uv一起往上走到最近公共祖先w的过程。令d = depth[u] - depth[w],虽然d是个未知值,但依然可以看成2的次方的和。从高位到低位枚举d的二进制位,设最低位为第0位,若枚举到第k位,有fa[k][u] != fa[k][v],则令u = fa[k][u]v = fa[k][v]。最后最近公共祖先w = fa[0][u] = fa[0][v],即uv的父亲。

倍增如何预处理:k=0时,fa[k][u]为u在有根树的父亲,令fa[k][root]=-1;k>0时,fa[k][u]=fa[k-1][fa[k-1][u]];

时间复杂度:预处理o(nlogn);单词查询o(longn);

tarjan离线算法:

离线算法是把所有询问储存下来,一次处理全部,求得答案。tarjian算法就是这样,要找两个点a,b的最近公共祖先,先dfs从a点遍历到b点。遍历到b时,路劲上除了外节点的子树都遍历过了,而子树没遍历完,对于a,访问完他的子树后就在a的并查集中的父亲设为他在树中的父亲,访问b是b在a并查集中的父亲就是最a和b的近公共祖先。

这样依次更新,bfs,知道发现1诶呦被搜过的点也没有关系点就退出。

程序实现:

 

 

 

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
二叉搜索(Binary Search Tree,简称BST)是一种特殊的二叉,它的每个节点的值都大于其左子的所有节点的值,且小于其右子的所有节点的值。最近公共祖先(Lowest Common Ancestor,简称LCA)是指在二叉两个节点p和q的最近公共祖先节点。 对于给定的二叉搜索,我们可以通过比较节点的值来确定最近公共祖先节点。具体步骤如下: 1. 从根节点开始遍历二叉搜索。 2. 如果当前节点的值大于p和q的值,说明p和q都在当前节点的左子,因此继续遍历当前节点的左子。 3. 如果当前节点的值小于p和q的值,说明p和q都在当前节点的右子,因此继续遍历当前节点的右子。 4. 如果当前节点的值介于p和q的值之间,说明当前节点就是最近公共祖先节点。 以下是一个示例代码,演示了如何找到二叉搜索最近公共祖先节点: ```python class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right def lowestCommonAncestor(root, p, q): if root.val > p.val and root.val > q.val: return lowestCommonAncestor(root.left, p, q) elif root.val < p.val and root.val < q.val: return lowestCommonAncestor(root.right, p, q) else: return root # 创建一个二叉搜索 root = TreeNode(6) root.left = TreeNode(2) root.right = TreeNode(8) root.left.left = TreeNode(0) root.left.right = TreeNode(4) root.right.left = TreeNode(7) root.right.right = TreeNode(9) root.left.right.left = TreeNode(3) root.left.right.right = TreeNode(5) # 找到节点3和节点5的最近公共祖先 p = TreeNode(3) q = TreeNode(5) lca = lowestCommonAncestor(root, p, q) print("最近公共祖先节点的值为:", lca.val) # 输出:2 ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值