📜  门| GATE-CS-2003 |问题2(1)

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

问题描述

本文将介绍 GATE-CS-2003 的第二个问题。该问题涉及到一个简单的算法,用于在二叉树中找到给定的两个节点的最小公共祖先。

问题详解

问题背景

给定一个二叉树和其中的两个节点,设计一个算法以找到它们的最小公共祖先。最小公共祖先是指在一棵树中同时拥有两个节点作为其后代的最深的节点。例如,对于以下二叉树:

        A
       / \
      B   C
     / \   \
    D   E   F

B 和 C 的最小公共祖先是 A,D 和 F 的最小公共祖先是 A,B 和 E 的最小公共祖先是 B。

问题分析

最小公共祖先问题是经典的树问题,解法有很多。在这里我们介绍一种简单的深度优先搜索算法。

从根节点开始遍历二叉树,如果当前节点为 p 或 q 中的一个,我们将其记为目标节点之一。然后继续遍历左右子树,如果在左子树中找到了目标节点之一,将其记为左子节点,如果在右子树中找到了目标节点之一,将其记为右子节点。如果左右子节点都不为空,说明当前节点为最小公共祖先,结束遍历;否则,继续向上找父节点进行搜索。

算法实现

该算法可以用递归实现。下面给出 Python 语言的实现代码。

# 定义二叉树结构
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

class Solution:
    def lowestCommonAncestor(self, root: TreeNode, p: TreeNode, q: TreeNode) -> TreeNode:
        if not root or root == p or root == q:
            return root
        left = self.lowestCommonAncestor(root.left, p, q)
        right = self.lowestCommonAncestor(root.right, p, q)
        if left and right:
            return root
        return left if left else right
算法分析

该算法的时间复杂度为 $O(n)$,其中 $n$ 是二叉树的节点个数。该算法需要遍历整棵树,遍历的时间复杂度为 $O(n)$,并且每个节点的访问最多只会发生一次。

由于遍历过程中不需要使用辅助空间,所以该算法的空间复杂度为 $O(1)$。

参考资料