# 「力扣」第 236 题:二叉树的最近公共祖先(后序遍历、分治思想)

下面两个链接其实是一个题目,选择一个做就可以了。

# 题目描述

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

百度百科 (opens new window) 中最近公共祖先的定义为:「对于有根树 T 的两个节点 pq,最近公共祖先表示为一个节点 x,满足 xpq 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。」

示例 1:

示例 1 配图

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

示例 2:

示例 2 配图

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

示例 3:

输入:root = [1, 2], p = 1, q = 2
输出:1

提示:

  • 树中节点数目在范围 [2, 10^5] 内;
  • -10^9 <= Node.val <= 10^9
  • 所有 Node.val 互不相同
  • p != q
  • pq 均存在于给定的二叉树中。

# 方法:后序遍历

  • 解决这道题的思想就是「后序遍历」:需要等左右子树都遍历完成以后,综合左右子树传递上来的结果,决定当前结点向上传递什么信息;
  • 通过这道问题,请大家重视「后序遍历」这个非常重要的思想(或者说解决问题的方法);
  • 具体讲解请见上方的视频题解(选择快速播放,不影响理解),视频来自今年 9 月份给「力扣」做的 4 场直播,地址在 这里 (opens new window),前 4 场是我讲的。

参考代码

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null || root == p || root == q) {
            return root;
        }

        TreeNode left = lowestCommonAncestor(root.left, p, q);
        TreeNode right = lowestCommonAncestor(root.right, p, q);
        if (left != null && right != null) {
            return root;
        }

        if (left == null) {
            return right;
        }
        return left;
    }
}

复杂度分析

  • 时间复杂度:,需要把整棵树看一遍,因此时间复杂度为
  • 空间复杂度:,最差情况下,二叉树成为单链表,因此空间复杂度为

作者:liweiwei1419 链接:https://suanfa8.com/tree/solutions/0236-lowest-common-ancestor-of-a-binary-tree 来源:算法吧 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Last Updated: 11/19/2024, 7:27:48 AM