返回

Python 实现寻找二叉树的最近公共祖先的两种方法

后端

前言

在计算机科学中,二叉树是一种重要的数据结构。二叉树的最近公共祖先(LCA)是两个节点的公共祖先中深度最大的节点。也就是说,最近公共祖先(LCA)是两个节点共享的最后一个祖先。

方法一:自顶向下

自顶向下的方法从根节点开始,并递归地遍历二叉树。在每个节点,它检查该节点是否是两个目标节点的最近公共祖先。如果该节点是最近公共祖先,则返回该节点。否则,它将继续递归遍历子树,直到找到最近公共祖先。

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

  参数:
    root: 二叉树的根节点。
    p: 目标节点之一。
    q: 目标节点之二。

  返回:
    两个目标节点的最近公共祖先。
  """

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

  # 如果根节点是目标节点之一,则返回根节点。
  if root == p or root == q:
    return root

  # 递归遍历左子树,并查找两个目标节点的最近公共祖先。
  left_lca = lowest_common_ancestor(root.left, p, q)

  # 递归遍历右子树,并查找两个目标节点的最近公共祖先。
  right_lca = lowest_common_ancestor(root.right, p, q)

  # 如果两个子树都找到了最近公共祖先,则返回根节点。
  if left_lca and right_lca:
    return root

  # 如果只有一个子树找到了最近公共祖先,则返回该子树的最近公共祖先。
  if left_lca:
    return left_lca
  if right_lca:
    return right_lca

  # 否则,返回 None。
  return None

方法二:自底向上

自底向上的方法从两个目标节点开始,并递归地向上遍历二叉树。在每个节点,它检查该节点是否是两个目标节点的最近公共祖先。如果该节点是最近公共祖先,则返回该节点。否则,它将继续递归遍历父节点,直到找到最近公共祖先。

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

  参数:
    root: 二叉树的根节点。
    p: 目标节点之一。
    q: 目标节点之二。

  返回:
    两个目标节点的最近公共祖先。
  """

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

  # 创建一个哈希表来存储每个节点的父节点。
  parent = {}

  # 使用深度优先搜索来填充哈希表。
  def dfs(node):
    if not node:
      return

    if node.left:
      parent[node.left] = node
      dfs(node.left)

    if node.right:
      parent[node.right] = node
      dfs(node.right)

  dfs(root)

  # 创建两个集合来存储两个目标节点的祖先。
  ancestors_p = set()
  ancestors_q = set()

  # 将两个目标节点的祖先添加到集合中。
  while p:
    ancestors_p.add(p)
    p = parent[p]

  while q:
    ancestors_q.add(q)
    q = parent[q]

  # 找到两个集合的交集,即两个目标节点的最近公共祖先。
  lca = ancestors_p & ancestors_q

  # 返回最近公共祖先。
  return lca.pop()

总结

本文介绍了两种使用 Python 语言实现查找二叉树最近公共祖先的方法。这两种方法都是基于递归的思想,并且都能够有效地找到二叉树中两个节点的最近公共祖先。