📌  相关文章
📜  二叉树中任意数量节点的最小公祖(1)

📅  最后修改于: 2023-12-03 15:21:39.914000             🧑  作者: Mango

二叉树中任意数量节点的最小公祖

二叉树中任意数量节点的最小公祖,即找到两个给定节点的最近公共祖先。这是一个常见的问题,在实际开发中常常需要解决。本文将介绍两种常见的解法:递归和迭代。

递归解法

递归解法比较容易理解,也比较直观。我们可以定义一个递归函数lowestCommonAncestor()来实现。

首先,我们需要思考几个特殊的情况:

  1. 如果根节点为空,返回None
  2. 如果根节点正好是其中一个节点,那么这个节点就是最近公共祖先,返回这个节点
  3. 如果根节点下面没有子节点了,返回None

如果不是上面的情况,我们就需要进一步判断根节点的左右子树。我们分别递归查找左右子树,并将结果保存在leftright中。如果leftright都不为空,那么根节点就是最近公共祖先,我们就可以直接返回。如果只有一个不为空,那么返回不为空的节点。如果都为空,返回None

下面是递归解法的代码实现(Python实现):

def lowestCommonAncestor(root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
    if not root:
        return None
    if root == p or root == q:
        return root
    left = lowestCommonAncestor(root.left, p, q)
    right = lowestCommonAncestor(root.right, p, q)
    if left and right:
        return root
    if left:
        return left
    if right:
        return right
    return None

上面的代码中,TreeNode表示二叉树的节点。输入参数root是二叉树的根节点,pq是需要查找的两个节点。

迭代解法

递归解法很好理解,但是由于递归过程中需要不断调用函数,所以有一定的空间复杂度。迭代解法是通过栈来实现的,可以降低空间复杂度。

迭代解法的思路也很简单:我们可以从根节点开始遍历二叉树,同时使用一个字典parent来记录每个节点的父节点。我们不断遍历p节点和q节点,直到找到他们的父节点是同一个节点为止。

下面是迭代解法的代码实现(Python实现):

def lowestCommonAncestor(root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
    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

上面的代码中,TreeNode表示二叉树的节点。输入参数root是二叉树的根节点,pq是需要查找的两个节点。我们使用栈来遍历二叉树,使用字典来记录每个节点的父节点。最后,我们返回找到的最近公共祖先节点。

总结

无论是递归解法还是迭代解法,都能够很好地解决二叉树中任意数量节点的最小公祖问题。在实际开发中,我们可以根据需求选择不同的解法实现。其中,递归解法比较常用,但是当二叉树比较大时,空间复杂度可能会比较高。迭代解法虽然代码量比较大,但是可以降低空间复杂度。