返回

用超级简单的语言解说 LeeCode 235:轻松找到二叉搜索树的最近公共祖先

前端

  1. 二叉搜索树是个什么鬼?

二叉搜索树是一种特殊类型的二叉树,它的特点是:

  • 每个节点最多有两个子节点,分别是左子节点和右子节点。
  • 左子节点的值小于父节点的值。
  • 右子节点的值大于父节点的值。

二叉搜索树的结构如下图所示:

             50
            /  \
           30   70
          / \   / \
        20  40  60  80

2. 什么是最近公共祖先?

最近公共祖先是两个节点的共同祖先中,离这两个节点最近的节点。在二叉搜索树中,最近公共祖先可以根据以下规则找到:

  • 如果两个节点都在父节点的左子树中,那么它们的最近公共祖先就是它们的父节点。
  • 如果两个节点都在父节点的右子树中,那么它们的最近公共祖先就是它们的父节点。
  • 如果一个节点在父节点的左子树中,另一个节点在父节点的右子树中,那么它们的最近公共祖先就是它们的父节点。

3. 如何找到最近公共祖先?

现在,我们知道了二叉搜索树的定义和最近公共祖先的定义,就可以开始学习如何找到最近公共祖先了。

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

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

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

    # 如果 p 和 q 分别在 root 的左右子树中
    return root

这个算法的时间复杂度是 O(h),其中 h 是二叉搜索树的高度。

4. 举个例子

现在,让我们举一个例子来理解这个算法。假设我们有一个二叉搜索树,如下图所示:

             50
            /  \
           30   70
          / \   / \
        20  40  60  80

如果我们要找到节点 20 和 80 的最近公共祖先,我们可以使用上面的算法:

  1. 从根节点 50 开始,比较 20 和 80 的值。20 小于 50,80 大于 50。因此,20 和 80 分别在 50 的左子树和右子树中。
  2. 现在,我们继续比较 20 和 80 的值。20 小于 30,80 大于 30。因此,20 和 80 分别在 30 的左子树和右子树中。
  3. 最后,我们继续比较 20 和 80 的值。20 小于 40,80 大于 40。因此,20 和 80 分别在 40 的左子树和右子树中。
  4. 现在,我们已经找到了 20 和 80 的最近公共祖先,它就是节点 40。

这就是如何找到二叉搜索树的最近公共祖先。