1、题目描述
236. 二叉树的最近公共祖先 - 力扣(LeetCode)
相关题:68-1二叉搜索树的最近公共祖先(剑)LeetCode.235 68-1:二叉搜索树的最近公共祖先(剑指offer第2版Python)LeetCode.235_leetcode 剑指 offer 68 - ii python-CSDN博客
2、代码详解
# Definition for a binary tree node.
class TreeNode(object):
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution(object):
def lowestCommonAncestor(self, root, p, q):
"""
:type root: TreeNode
:type p: TreeNode
:type q: TreeNode
:rtype: TreeNode
"""
# 若当前节点为空,或者当前节点就是 p 或 q 节点,直接返回当前节点
if not root or root == p or root == q:
return root
# 递归遍历左子树,查找 p 和 q 的最近公共祖先
left = self.lowestCommonAncestor(root.left, p, q)
# 递归遍历右子树,查找 p 和 q 的最近公共祖先
right = self.lowestCommonAncestor(root.right, p, q)
# 情况 1:左子树和右子树都没有找到 p 和 q,说明 p 和 q 不在当前节点的子树中,返回 None
if not left and not right:
return None
# 情况 2:左子树没有找到 p 和 q,说明 p 和 q 都在右子树中,返回右子树的查找结果
if not left:
return right
# 情况 3:右子树没有找到 p 和 q,说明 p 和 q 都在左子树中,返回左子树的查找结果
if not right:
return left
# 情况 4:左子树和右子树都找到了 p 或 q,说明 p 和 q 分别在当前节点的左右子树中,当前节点就是最近公共祖先,返回当前节点
return root
def main():
# 构建一个简单的二叉树
# 3
# / \
# 5 1
# /| |\
# 6 2 0 8
# |\
# 7 4
root = TreeNode(3)
root.left = TreeNode(5)
root.right = TreeNode(1)
root.left.left = TreeNode(6)
root.left.right = TreeNode(2)
root.right.left = TreeNode(0)
root.right.right = TreeNode(8)
root.left.right.left = TreeNode(7)
root.left.right.right = TreeNode(4)
# 假设要查找 5 和 1 的最近公共祖先
p = root.left # 节点 5
q = root.right # 节点 1
solution = Solution()
# 调用 lowestCommonAncestor 方法查找最近公共祖先
result = solution.lowestCommonAncestor(root, p, q)
if result:
print(f"节点 {p.val} 和节点 {q.val} 的最近公共祖先是节点 {result.val}")
else:
print("未找到最近公共祖先")
if __name__ == "__main__":
main()
复杂度分析:
时间O(N) : 其中 N 为二叉树节点数;最差情况下,需要递归遍历树的所有节点。
空间O(H) :其中 H是二叉树的高度。递归调用栈的深度最大为二叉树的高度。在最坏情况下,二叉树退化为链表,空间复杂度为 O(N) 。
https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-tree/solutions/240096/236-er-cha-shu-de-zui-jin-gong-gong-zu-xian-hou-xu/
# Definition for a binary tree node.
class TreeNode(object):
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution(object):
def lowestCommonAncestor(self, root, p, q):
"""
:type root: TreeNode
:type p: TreeNode
:type q: TreeNode
:rtype: TreeNode
"""
if not root or root == p or root == q:
return root
# 通过递归对二叉树进行 后序遍历,当遇到节点 p 或 q 时返回。
# 从底至顶回溯,当节点 p, q 在节点 root 的异侧时,节点 root 即为最近公共祖先,则向上返回 root 。
left = self.lowestCommonAncestor(root.left, p, q)
right = self.lowestCommonAncestor(root.right, p, q)
if not left and not right:
return # 1.说明 root 的左 / 右子树中都不包含 p,q,返回 null
if not left:
# 3.p,q 都不在 root 的左子树中,直接返回 right,具体可分为两种情况:
# p,q 其中一个在 root 的 右子树 中,此时 right 指向 p(假设为 p )
# p,q 两节点都在 root 的 右子树 中,此时的 right 指向 最近公共祖先节点
return right
if not right:
return left # 4.同理3
return root # 2. if left and right: 同时不为空 :说明 p, q 分列在 root 的 异侧 (分别在 左 / 右子树),因此 root 为最近公共祖先,返回 root