Skip to main content

236.二叉树的最近公共祖先

标签: tree, depth-first-search

难度: Medium

通过率: 64.85%

原题链接: https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/description/

题目描述

给定一棵二叉树,找到两个指定节点的最近公共祖先(LCA)。根据维基百科中LCA的定义:“最近公共祖先是两节点在树中最低的公共祖先节点(节点允许作为其后代)。”

解题思路

题目要求找到二叉树中两个节点的最低公共祖先(LCA)。可以用递归的方法来解决这个问题。

  1. 基本思路:

    • 如果当前节点是 None,返回 None
    • 如果当前节点等于 pq,那么当前节点就是最低公共祖先。
    • 对左右子树递归查找:
      • 如果左右子树的递归结果都不为 None,说明 pq 分别位于当前节点的两侧,当前节点就是最低公共祖先。
      • 如果左右子树中只有一个递归结果不为 None,则说明最低公共祖先在另一侧。
  2. 递归函数逻辑:

    • 如果当前节点是 pq,直接返回当前节点。
    • 递归搜索左子树和右子树。
    • 根据左右子树返回值判断是否找到最低公共祖先。

代码实现

# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None

class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
# 如果当前节点为空,返回 None
if not root:
return None

# 如果当前节点是 p 或 q,返回当前节点
if root == p or root == q:
return root

# 递归搜索左子树和右子树
left = self.lowestCommonAncestor(root.left, p, q)
right = self.lowestCommonAncestor(root.right, p, q)

# 如果左右子树都有返回值,说明当前节点是最低公共祖先
if left and right:
return root

# 如果只有一侧有返回值,返回那一侧
return left if left else right

复杂度分析

时间复杂度:O(n)O(n),其中nn是树中的节点数量。递归遍历每个节点一次。

空间复杂度:O(n)O(n),用于递归堆栈。当树为平衡树时,递归深度为 O(extlogn)O( ext{log}n),最坏情况下递归深度为 O(n)O(n)

这段代码可以解决通用二叉树的最低公共祖先问题,而不仅限于二叉搜索树。