返回

如何直击本质,深入理解二叉树中的最近公共祖先?

闲谈

最近公共祖先的定义和意义

在二叉树中,两个节点的最近公共祖先(LCA)是指这两个节点在树中最近的共同祖先。换句话说,LCA是这两个节点在树中最低的公共祖先节点。

最近公共祖先的概念在许多计算机科学问题中都非常有用,例如:

  • 计算两个节点之间的距离
  • 查找两个节点之间的路径
  • 检测两个节点是否在同一条路径上
  • 寻找二叉树的直径
  • 将二叉树拆分成两个子树

寻找最近公共祖先的三种经典算法

1. 递归算法

递归算法是最简单、最直接的最近公共祖先算法。其核心思想是,如果给定两个节点的父节点是同一个节点,那么这个父节点就是这两个节点的最近公共祖先。否则,分别递归寻找这两个节点的父节点的最近公共祖先,即可找到这两个节点的最近公共祖先。

def lowest_common_ancestor(root, p, q):
  if root is None:
    return None
  if root == p or root == q:
    return root
  left = lowest_common_ancestor(root.left, p, q)
  right = lowest_common_ancestor(root.right, p, q)
  if left and right:
    return root
  return left or right

2. 迭代算法

迭代算法与递归算法类似,但它使用栈来存储节点,而不是使用递归调用。这使得迭代算法在内存使用上更加高效,但它可能更难理解。

def lowest_common_ancestor(root, p, q):
  stack = [root]
  parent = {root: None}
  while p not in parent or q not in parent:
    node = stack.pop()
    if node.left:
      parent[node.left] = node
      stack.append(node.left)
    if node.right:
      parent[node.right] = node
      stack.append(node.right)

  ancestors = set()
  while p:
    ancestors.add(p)
    p = parent[p]

  while q not in ancestors:
    q = parent[q]

  return q

3. 二叉树中心算法

二叉树中心算法是另一种查找最近公共祖先的算法。其核心思想是,找到二叉树的中心节点,然后从中心节点开始向上搜索,直到找到这两个节点的最近公共祖先。

def lowest_common_ancestor(root, p, q):
  def find_center(root):
    if root is None:
      return None, 0
    left_center, left_size = find_center(root.left)
    right_center, right_size = find_center(root.right)
    size = left_size + right_size + 1
    if left_size == right_size:
      return root, size
    elif left_size > right_size:
      return left_center, size
    else:
      return right_center, size

  center, size = find_center(root)
  while size > 2:
    if p in center.left and q in center.left:
      center, size = find_center(center.left)
    elif p in center.right and q in center.right:
      center, size = find_center(center.right)
    else:
      break

  return center

结语

在本文中,我们深入探讨了二叉树中最近公共祖先的概念,并介绍了三种经典算法来解决该问题。希望这些知识能够帮助您更好地理解二叉树,并解决相关的问题。