相似题目:

  1. 【LeetCode】235. 二叉搜索树的最近公共祖先
  2. 【LeetCode】572. 另一个树的子树
  3. 【LeetCode】104. 二叉树的最大深度【简单】
  4. 【LeetCode】110. 平衡二叉树
  5. 【LeetCode】297. 二叉树的序列化与反序列化【困难】
  6. 【LeetCode】226.翻转二叉树

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。因为根据定义最近公共祖先节点可以为节点本身。

说明:

所有节点的值都是唯一的。
p、q 为不同节点且均存在于给定的二叉树中。

2. 解题思路 & 代码

  • 如果root为 null,肯定返回 null;

  • 如果root的值等于其中的某一个,那么就返回这个值;

  • 如果root的值和两个都不相等,递归的判断左右孩子;

  • 如果返回左右孩子的两个值都不为null,说明root节点的左右子树中各有一个,返回root即可!若其中一个为null,返回另一个即可(说明在一边的子树中,首先遍历到的肯定是所要求的节点了)!

    分情况讨论

    1. root子树中同时包含p和q, 返回root
    2. root中只有p, 返回p
    3. root中只有q, 返回q
    4. root中既然没有p, 也没有q, 返回null
# 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':
        if not root or root.val == p.val or root.val == q.val:
            return root
        left = self.lowestCommonAncestor(root.left, p, q)
        right = self.lowestCommonAncestor(root.right, p, q)
        if not left:       # p 和 q 不在左边,往右边找
            return right
        if not right:      # p 和 q 不在右边,往左边找
            return left
        if left and right: # 左右都不为空,说明 p,q 分别在左右子树中,之间返回 root 即可
            return root
        

参考:

  1. LeetCode 题解