返回

图解 LeetCode:剑指 Offer 68 - I. 二叉搜索树的最近公共祖先

后端

二叉搜索树的最近公共祖先:一步步轻松理解

在二叉搜索树 (BST) 中,最近公共祖先 (LCA) 是两个节点的最低共同祖先。换句话说,LCA 是两个节点向上追溯到树中第一个共同祖先的节点。

理解二叉搜索树的最近公共祖先的概念对于解决 LeetCode 上的「剑指 Offer 68 - I. 二叉搜索树的最近公共祖先」问题至关重要。

背景知识:二叉搜索树

在开始之前,让我们快速回顾一下二叉搜索树的基本概念:

  • 定义: 二叉搜索树 (BST) 是一种特殊的二叉树,其中每个节点的值都大于其左子树中的所有节点值,而小于其右子树中的所有节点值。
  • 查找: 由于 BST 的排序性质,我们可以通过递归地将目标值与节点值进行比较来高效地查找一个节点。
  • 插入: 为了保持 BST 的排序特性,当我们插入一个新节点时,必须根据目标值与当前节点值的关系将其插入到正确的位置。

理解算法

要找到 BST 中两个节点的 LCA,我们可以采用以下直观的步骤:

  1. 比较节点值: 首先,如果两个节点的值相同,那么它们就是彼此的 LCA。
  2. 遍历 BST: 从 BST 的根节点开始,将两个节点的值与当前节点的值进行比较。
  3. 定位 LCA: 如果当前节点的值比两个节点的值都大,则 LCA 肯定在左子树中。同样,如果当前节点的值比两个节点的值都小,则 LCA 肯定在右子树中。
  4. 递归查找: 重复步骤 2-3,直到找到 LCA。

代码示例

以下是用 Python 实现的算法代码示例:

def lowest_common_ancestor(root, p, q):
    if not root or root == p or root == q:
        return root

    if p.val < root.val < q.val:
        return root

    elif p.val < root.val and q.val < root.val:
        return lowest_common_ancestor(root.left, p, q)

    elif p.val > root.val and q.val > root.val:
        return lowest_common_ancestor(root.right, p, q)

时间和空间复杂度

  • 时间复杂度: O(log n),其中 n 是 BST 中的节点数。算法最坏情况下会遍历从根节点到 LCA 的路径,该路径的长度最多为树的高度。BST 的平均高度为 O(log n),因此算法的时间复杂度为 O(log n)。
  • 空间复杂度: O(1),因为算法不需要额外的空间来存储中间结果。

总结

理解二叉搜索树的最近公共祖先的概念对于解决二叉搜索树相关问题至关重要。通过比较、遍历和递归查找的结合,我们可以有效地找到 BST 中两个节点的 LCA。

常见问题解答

  1. 什么是二叉搜索树?
    二叉搜索树是一种特殊的二叉树,其中每个节点的值都大于其左子树中的所有节点值,而小于其右子树中的所有节点值。

  2. 最近公共祖先的定义是什么?
    最近公共祖先是两个节点向上追溯到树中第一个共同祖先的节点。

  3. 如何找到 BST 中两个节点的 LCA?
    我们可以通过比较节点值、遍历 BST 和递归查找来找到 LCA。

  4. 该算法的时间复杂度是多少?
    算法的时间复杂度为 O(log n),其中 n 是 BST 中的节点数。

  5. 该算法的空间复杂度是多少?
    算法的空间复杂度为 O(1)。