返回

二叉查找树的最近公共祖先

后端

引言

在二叉查找树中,每个节点的值都比其左子树的所有节点的值大,比其右子树的所有节点的值小。给定一个二叉查找树和两个节点,找到这两个节点的最近公共祖先。最近公共祖先是指两个节点的最近共同祖先。

解题思路

可以使用深度优先搜索(DFS)算法来求解这个问题。DFS 算法是一种在树或图中遍历节点的搜索算法。该算法在进入子节点之前会尽可能遍历一个节点的所有子节点。

可以使用两种 DFS 算法来求解这个问题。

  • 方案一: 使用递归的 DFS 算法。
  • 方案二: 使用循环的 DFS 算法。

方案一:使用递归的 DFS 算法

可以使用递归的 DFS 算法来求解这个问题。DFS 算法是一种在树或图中遍历节点的搜索算法。该算法在进入子节点之前会尽可能遍历一个节点的所有子节点。

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

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

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

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

方案二:使用循环的 DFS 算法

可以使用循环的 DFS 算法来求解这个问题。DFS 算法是一种在树或图中遍历节点的搜索算法。该算法在进入子节点之前会尽可能遍历一个节点的所有子节点。

def lowest_common_ancestor(root, p, q):
    stack = [root]
    parent = {root: None}

    # 找到 p 和 q 的最近公共祖先
    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)

    # 找到 p 和 q 的最近公共祖先
    ancestors = set()
    while p:
        ancestors.add(p)
        p = parent[p]

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

    return q

性能分析

两种 DFS 算法的时间复杂度都是 O(n),其中 n 是二叉查找树的节点数。空间复杂度也是 O(n),因为 DFS 算法需要使用栈来存储节点。

总结

本文详细解析了如何利用深度优先搜索算法求解二叉查找树的最近公共祖先问题。深度优先搜索是一种在树或图中遍历节点的搜索算法,该算法在进入子节点之前会尽可能遍历一个节点的所有子节点。本文给出了两个使用深度优先搜索求解最近公共祖先的方案,方案一采用了递归的思想,方案二则是利用循环来完成。通过这些例题,读者能够掌握深度优先搜索算法的原理和使用方式。