返回

揭开数据结构之谜:二叉树公共祖先的探索之旅

前端

LeetCode算法学习之--Recursion--二叉树的最近公共祖先

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

大家好,今天给大家分享下一道LeetCode中等难度的题目236. 二叉树的最近公共祖先。

(图片来自leetcode)

分析

这道题考察的是二叉树的公共祖先的查找。给定一个二叉树和两个节点,找到这两个节点的最近公共祖先。最近公共祖先是指,在给定的二叉树中,这两个节点的最近的共同祖先。

解法

这道题可以采用递归的方法来解决。递归的定义是,一个函数调用自身来完成任务。在本题中,我们可以将二叉树分成三部分:

  1. 左子树
  2. 右子树
  3. 当前节点

如果这两个节点都在左子树中,那么这两个节点的最近公共祖先就在左子树中。如果这两个节点都在右子树中,那么这两个节点的最近公共祖先就在右子树中。如果这两个节点一个在左子树中,一个在右子树中,那么这两个节点的最近公共祖先就是当前节点。

根据这个思路,我们可以编写出如下递归函数:

def find_lca(root, p, q):
  if not root:
    return None

  # 如果p和q都在左子树中
  if root.left and find_lca(root.left, p, q):
    return find_lca(root.left, p, q)

  # 如果p和q都在右子树中
  if root.right and find_lca(root.right, p, q):
    return find_lca(root.right, p, q)

  # 如果p和q一个在左子树中,一个在右子树中
  if root.left and root.right and find_lca(root.left, p, q) and find_lca(root.right, p, q):
    return root

  # 如果p和q都等于root
  if root.val == p.val and root.val == q.val:
    return root

  # 如果p等于root
  if root.val == p.val:
    return p

  # 如果q等于root
  if root.val == q.val:
    return q

  # 如果p和q都不在二叉树中
  return None

这个递归函数的复杂度是O(n),其中n是二叉树的节点数。

示例

# 创建一个二叉树
root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
root.left.left = TreeNode(4)
root.left.right = TreeNode(5)
root.right.left = TreeNode(6)
root.right.right = TreeNode(7)

# 查找两个节点的最近公共祖先
lca = find_lca(root, TreeNode(4), TreeNode(5))

# 打印最近公共祖先的值
print(lca.val)  # 2

总结

这道题考察的是二叉树的公共祖先的查找。给定一个二叉树和两个节点,找到这两个节点的最近公共祖先。最近公共祖先是指,在给定的二叉树中,这两个节点的最近的共同祖先。这道题可以采用递归的方法来解决。递归的定义是,一个函数调用自身来完成任务。在本题中,我们可以将二叉树分成三部分:左子树、右子树和当前节点。如果这两个节点都在左子树中,那么这两个节点的最近公共祖先就在左子树中。如果这两个节点都在右子树中,那么这两个节点的最近公共祖先就在右子树中。如果这两个节点一个在左子树中,一个在右子树中,那么这两个节点的最近公共祖先就是当前节点。根据这个思路,我们可以编写出如下递归函数:

def find_lca(root, p, q):
  if not root:
    return None

  # 如果p和q都在左子树中
  if root.left and find_lca(root.left, p, q):
    return find_lca(root.left, p, q)

  # 如果p和q都在右子树中
  if root.right and find_lca(root.right, p, q):
    return find_lca(root.right, p, q)

  # 如果p和q一个在左子树中,一个在右子树中
  if root.left and root.right and find_lca(root.left, p, q) and find_lca(root.right, p, q):
    return root

  # 如果p和q都等于root
  if root.val == p.val and root.val == q.val:
    return root

  # 如果p等于root
  if root.val == p.val:
    return p

  # 如果q等于root
  if root.val == q.val:
    return q

  # 如果p和q都不在二叉树中
  return None

这个递归函数的复杂度是O(n),其中n是二叉树的节点数。