返回
手撸二叉树之二叉树的最近公共祖先
前端
2023-11-13 00:05:52
大家好,今天我将带大家一起探索二叉树中两个节点的最近公共祖先。什么是最近公共祖先呢?我们先来看一个例子。
给定二叉树:[3,5,1,6,2,0,8,null,null,7,4],其中 5 和 1 是两个节点。它们的最近公共祖先是 3。
再举一个例子,给定二叉树:[3,5,1,6,2,0,8,null,null,7,4],其中 5 和 4 是两个节点。它们的最近公共祖先是 5。
现在我们已经了解了什么是最近公共祖先,接下来我们就来看一下如何求解。我们首先来看一种简单的递归算法:
- 如果根节点为空,则返回空。
- 如果根节点是其中一个节点,则返回根节点。
- 如果根节点不是其中一个节点,则分别递归地查找左子树和右子树。
- 如果在左子树和右子树中都找到了节点,则返回根节点。
- 如果只在左子树或右子树中找到了一个节点,则返回找到的节点。
代码如下:
def lowest_common_ancestor(root, p, q):
if not root:
return None
if root == p or root == q:
return root
left = lowest_common_ancestor(root.left, p, q)
right = lowest_common_ancestor(root.right, p, q)
if left and right:
return root
return left or right
这种算法的时间复杂度是 O(n),空间复杂度是 O(h),其中 n 是二叉树的节点数,h 是二叉树的高度。
现在我们再来介绍一种更优的算法:
- 我们先将二叉树转换成一个哈希表,其中键是节点的值,值是节点的父节点。
- 然后,我们可以通过查找两个节点的父节点来找到它们的最近公共祖先。
代码如下:
def lowest_common_ancestor(root, p, q):
parent = {}
def dfs(node):
if not node:
return
parent[node.val] = node.parent
dfs(node.left)
dfs(node.right)
dfs(root)
ancestors = set()
while p:
ancestors.add(p)
p = parent[p]
while q:
if q in ancestors:
return q
q = parent[q]
return None
这种算法的时间复杂度是 O(n),空间复杂度也是 O(n)。
希望通过本文,大家能够对二叉树的最近公共祖先有更深入的了解。