剑指 Offer 68 - II. 二叉树的最近公共祖先

646 阅读1分钟

题目描述

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

例如,给定如下二叉树: root = [3,5,1,6,2,0,8,null,null,7,4]

示例 1: 输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1 输出: 3 解释: 节点 5 和节点 1 的最近公共祖先是节点 3。

示例 2: 输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4 输出: 5 解释: 节点 5 和节点 4 的最近公共祖先是节点 5。因为根据定义最近公共祖先节点可以为节点本身。

解题思路

  1. 与68-1不同, 这个题目不是二叉排序树, 所以我们不能单从大小来判断出祖先节点; 所以我们使用递归来处理
  2. 直接递归根节点的左右节点, 判断子节点是否与p, q相同, 如果相同, 则返回; 不相同就一直递归到nil
  3. 递归到子节点时, 我们拿到了left, 和right, 他们的值可能是 p, q或nil. 如果left为nil, 返回right; 如果right为nil, 返回left; 如果都不为nil, 则返回root, 此时root 公共祖先, 将root依次向上返回

示例代码

def lowestCommonAncestor(
    self, root: TreeNode, p: TreeNode, q: TreeNode
) -> TreeNode:
    if not root or root == p or root == q:
        return root
    left = self.lowestCommonAncestor(root.left, p, q)
    right = self.lowestCommonAncestor(root.right, p, q)
    if not left:
        return right
    if not right:
        return left
    return root