📅  最后修改于: 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)$。