返回
Python 实现寻找二叉树的最近公共祖先的两种方法
后端
2023-09-30 20:54:39
前言
在计算机科学中,二叉树是一种重要的数据结构。二叉树的最近公共祖先(LCA)是两个节点的公共祖先中深度最大的节点。也就是说,最近公共祖先(LCA)是两个节点共享的最后一个祖先。
方法一:自顶向下
自顶向下的方法从根节点开始,并递归地遍历二叉树。在每个节点,它检查该节点是否是两个目标节点的最近公共祖先。如果该节点是最近公共祖先,则返回该节点。否则,它将继续递归遍历子树,直到找到最近公共祖先。
def lowest_common_ancestor(root, p, q):
"""
找到二叉树中两个节点的最近公共祖先。
参数:
root: 二叉树的根节点。
p: 目标节点之一。
q: 目标节点之二。
返回:
两个目标节点的最近公共祖先。
"""
# 如果根节点为空,则返回 None。
if not root:
return None
# 如果根节点是目标节点之一,则返回根节点。
if root == p or root == q:
return root
# 递归遍历左子树,并查找两个目标节点的最近公共祖先。
left_lca = lowest_common_ancestor(root.left, p, q)
# 递归遍历右子树,并查找两个目标节点的最近公共祖先。
right_lca = lowest_common_ancestor(root.right, p, q)
# 如果两个子树都找到了最近公共祖先,则返回根节点。
if left_lca and right_lca:
return root
# 如果只有一个子树找到了最近公共祖先,则返回该子树的最近公共祖先。
if left_lca:
return left_lca
if right_lca:
return right_lca
# 否则,返回 None。
return None
方法二:自底向上
自底向上的方法从两个目标节点开始,并递归地向上遍历二叉树。在每个节点,它检查该节点是否是两个目标节点的最近公共祖先。如果该节点是最近公共祖先,则返回该节点。否则,它将继续递归遍历父节点,直到找到最近公共祖先。
def lowest_common_ancestor(root, p, q):
"""
找到二叉树中两个节点的最近公共祖先。
参数:
root: 二叉树的根节点。
p: 目标节点之一。
q: 目标节点之二。
返回:
两个目标节点的最近公共祖先。
"""
# 如果根节点为空,则返回 None。
if not root:
return None
# 创建一个哈希表来存储每个节点的父节点。
parent = {}
# 使用深度优先搜索来填充哈希表。
def dfs(node):
if not node:
return
if node.left:
parent[node.left] = node
dfs(node.left)
if node.right:
parent[node.right] = node
dfs(node.right)
dfs(root)
# 创建两个集合来存储两个目标节点的祖先。
ancestors_p = set()
ancestors_q = set()
# 将两个目标节点的祖先添加到集合中。
while p:
ancestors_p.add(p)
p = parent[p]
while q:
ancestors_q.add(q)
q = parent[q]
# 找到两个集合的交集,即两个目标节点的最近公共祖先。
lca = ancestors_p & ancestors_q
# 返回最近公共祖先。
return lca.pop()
总结
本文介绍了两种使用 Python 语言实现查找二叉树最近公共祖先的方法。这两种方法都是基于递归的思想,并且都能够有效地找到二叉树中两个节点的最近公共祖先。