返回

找出二叉搜索树中目标节点的最近公共祖先

前端

算法概述

在二叉搜索树中,每个节点的值都大于其左子树的所有节点的值,而小于其右子树的所有节点的值。利用这一特性,我们可以通过比较目标节点的值来确定其最近公共祖先。

最近公共祖先的算法步骤如下:

  1. 从根节点开始。
  2. 如果目标节点的值等于当前节点的值,则当前节点即为最近公共祖先。
  3. 如果目标节点的值小于当前节点的值,则最近公共祖先一定在当前节点的左子树中,因此将当前节点更新为其左子节点,然后重复步骤1。
  4. 如果目标节点的值大于当前节点的值,则最近公共祖先一定在当前节点的右子树中,因此将当前节点更新为其右子节点,然后重复步骤1。
  5. 重复步骤2-4,直到找到最近公共祖先。

代码实现

def lowest_common_ancestor(root, p, q):
  """
  找出二叉搜索树中两个目标节点的最近公共祖先。

  参数:
    root: 二叉搜索树的根节点。
    p: 目标节点1。
    q: 目标节点2。

  返回值:
    最近公共祖先节点。
  """

  # 如果根节点为空,则返回空。
  if not root:
    return None

  # 如果目标节点1和目标节点2的值都小于根节点的值,
  # 则最近公共祖先一定在根节点的左子树中。
  if p.val < root.val and q.val < root.val:
    return lowest_common_ancestor(root.left, p, q)

  # 如果目标节点1和目标节点2的值都大于根节点的值,
  # 则最近公共祖先一定在根节点的右子树中。
  if p.val > root.val and q.val > root.val:
    return lowest_common_ancestor(root.right, p, q)

  # 如果目标节点1的值小于根节点的值,
  # 而目标节点2的值大于根节点的值,
  # 则根节点即为最近公共祖先。
  return root

示例

考虑以下二叉搜索树:

        10
       /  \
      5    15
     / \    /  \
    2   7  12   20

如果目标节点1是2,目标节点2是12,则最近公共祖先是5。

如果目标节点1是2,目标节点2是20,则最近公共祖先是10。

如果目标节点1是5,目标节点2是15,则最近公共祖先是10。

算法分析

最近公共祖先算法的时间复杂度为O(log n),其中n是二叉搜索树的节点数。这是因为在每一步中,我们都将搜索范围缩小一半。

最近公共祖先算法的空间复杂度为O(1),因为我们不需要额外的空间来存储中间结果。

结语

最近公共祖先算法是一个重要的算法,在许多应用中都有广泛的使用,例如查找文件系统的公共祖先目录、查找代码库中的公共祖先分支等。通过本文的讲解,相信您已经对最近公共祖先算法有了深入的理解。