返回
一道考验思考,颇具脑洞的 leetcode 题目,测试你的解决问题能力和代码实现能力
前端
2023-10-20 01:01:42
大家好,欢迎来到我的刷题打卡专栏。今天,我们一起来挑战 LeetCode 236 题“二叉树的最近公共祖先”。这道题要求你找出二叉树中两个指定节点的最近公共祖先,即这两个节点的共同祖先中深度最大的一个。
题目
给定一个二叉树,找出两个指定节点 p 和 q 的最近公共祖先。
示例:
给定以下二叉树:
1
/ \
2 3
/ \
4 5
若 p = 4,q = 5,则它们的最近公共祖先是节点 2。
解法:
这道题可以采用递归的方法来解决。递归的基本思想是将一个大问题分解成一系列较小的子问题,然后递归地解决这些子问题,最后将子问题的解组合起来得到大问题的解。
在二叉树中,最近公共祖先可以通过以下步骤来找到:
- 如果 p 和 q 都在左子树中,则最近公共祖先在左子树中。
- 如果 p 和 q 都在右子树中,则最近公共祖先在右子树中。
- 如果 p 和 q 分别在左子树和右子树中,则最近公共祖先是当前节点。
根据以上步骤,我们可以写出以下递归算法:
def lowest_common_ancestor(root, p, q):
if not root:
return None
# 如果 p 和 q 都在左子树中
if root.val > p.val and root.val > q.val:
return lowest_common_ancestor(root.left, p, q)
# 如果 p 和 q 都在右子树中
if root.val < p.val and root.val < q.val:
return lowest_common_ancestor(root.right, p, q)
# 如果 p 和 q 分别在左子树和右子树中
return root
代码实现:
class Node:
def __init__(self, val):
self.val = val
self.left = None
self.right = None
def lowest_common_ancestor(root, p, q):
if not root:
return None
# 如果 p 和 q 都在左子树中
if root.val > p.val and root.val > q.val:
return lowest_common_ancestor(root.left, p, q)
# 如果 p 和 q 都在右子树中
if root.val < p.val and root.val < q.val:
return lowest_common_ancestor(root.right, p, q)
# 如果 p 和 q 分别在左子树和右子树中
return root
# 测试代码
root = Node(1)
root.left = Node(2)
root.right = Node(3)
root.left.left = Node(4)
root.left.right = Node(5)
p = root.left.left
q = root.left.right
lca = lowest_common_ancestor(root, p, q)
print(lca.val) # 输出 2
时间复杂度:
算法的时间复杂度为 O(n),其中 n 是二叉树的节点数。这是因为算法需要遍历整个二叉树一次。
空间复杂度:
算法的空间复杂度为 O(h),其中 h 是二叉树的高度。这是因为算法需要使用一个栈来存储递归调用的状态。
总结:
LeetCode 236 题“二叉树的最近公共祖先”是一个经典的算法问题,旨在测试你的解决问题能力和代码实现能力。这道题要求你找出二叉树中两个指定节点的最近公共祖先,即这两个节点的共同祖先中深度最大的一个。本文从问题分析、算法设计和代码实现三个方面详细讲解了这道题的解法,希望对各位程序员和算法爱好者有所帮助。