揭开数据结构之谜:二叉树公共祖先的探索之旅
2023-12-10 14:32:33
LeetCode算法学习之--Recursion--二叉树的最近公共祖先
小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
大家好,今天给大家分享下一道LeetCode中等难度的题目236. 二叉树的最近公共祖先。
(图片来自leetcode)
分析
这道题考察的是二叉树的公共祖先的查找。给定一个二叉树和两个节点,找到这两个节点的最近公共祖先。最近公共祖先是指,在给定的二叉树中,这两个节点的最近的共同祖先。
解法
这道题可以采用递归的方法来解决。递归的定义是,一个函数调用自身来完成任务。在本题中,我们可以将二叉树分成三部分:
- 左子树
- 右子树
- 当前节点
如果这两个节点都在左子树中,那么这两个节点的最近公共祖先就在左子树中。如果这两个节点都在右子树中,那么这两个节点的最近公共祖先就在右子树中。如果这两个节点一个在左子树中,一个在右子树中,那么这两个节点的最近公共祖先就是当前节点。
根据这个思路,我们可以编写出如下递归函数:
def find_lca(root, p, q):
if not root:
return None
# 如果p和q都在左子树中
if root.left and find_lca(root.left, p, q):
return find_lca(root.left, p, q)
# 如果p和q都在右子树中
if root.right and find_lca(root.right, p, q):
return find_lca(root.right, p, q)
# 如果p和q一个在左子树中,一个在右子树中
if root.left and root.right and find_lca(root.left, p, q) and find_lca(root.right, p, q):
return root
# 如果p和q都等于root
if root.val == p.val and root.val == q.val:
return root
# 如果p等于root
if root.val == p.val:
return p
# 如果q等于root
if root.val == q.val:
return q
# 如果p和q都不在二叉树中
return None
这个递归函数的复杂度是O(n),其中n是二叉树的节点数。
示例
# 创建一个二叉树
root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
root.left.left = TreeNode(4)
root.left.right = TreeNode(5)
root.right.left = TreeNode(6)
root.right.right = TreeNode(7)
# 查找两个节点的最近公共祖先
lca = find_lca(root, TreeNode(4), TreeNode(5))
# 打印最近公共祖先的值
print(lca.val) # 2
总结
这道题考察的是二叉树的公共祖先的查找。给定一个二叉树和两个节点,找到这两个节点的最近公共祖先。最近公共祖先是指,在给定的二叉树中,这两个节点的最近的共同祖先。这道题可以采用递归的方法来解决。递归的定义是,一个函数调用自身来完成任务。在本题中,我们可以将二叉树分成三部分:左子树、右子树和当前节点。如果这两个节点都在左子树中,那么这两个节点的最近公共祖先就在左子树中。如果这两个节点都在右子树中,那么这两个节点的最近公共祖先就在右子树中。如果这两个节点一个在左子树中,一个在右子树中,那么这两个节点的最近公共祖先就是当前节点。根据这个思路,我们可以编写出如下递归函数:
def find_lca(root, p, q):
if not root:
return None
# 如果p和q都在左子树中
if root.left and find_lca(root.left, p, q):
return find_lca(root.left, p, q)
# 如果p和q都在右子树中
if root.right and find_lca(root.right, p, q):
return find_lca(root.right, p, q)
# 如果p和q一个在左子树中,一个在右子树中
if root.left and root.right and find_lca(root.left, p, q) and find_lca(root.right, p, q):
return root
# 如果p和q都等于root
if root.val == p.val and root.val == q.val:
return root
# 如果p等于root
if root.val == p.val:
return p
# 如果q等于root
if root.val == q.val:
return q
# 如果p和q都不在二叉树中
return None
这个递归函数的复杂度是O(n),其中n是二叉树的节点数。