# 「力扣」第 236 题:二叉树的最近公共祖先(后序遍历、分治思想)
下面两个链接其实是一个题目,选择一个做就可以了。
- 题目链接:236. 二叉树的最近公共祖先 (opens new window);
- 题目链接:剑指 Offer 68 - II. 二叉树的最近公共祖先 - 力扣(LeetCode) (opens new window) 。
# 题目描述
给定一个二叉树,找到该树中两个指定节点的最近公共祖先。
百度百科 (opens new window) 中最近公共祖先的定义为:「对于有根树 T 的两个节点 p
、q
,最近公共祖先表示为一个节点 x
,满足 x
是 p
、q
的祖先且 x
的深度尽可能大(一个节点也可以是它自己的祖先)。」
示例 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 。因为根据定义最近公共祖先节点可以为节点本身。
示例 3:
输入:root = [1, 2], p = 1, q = 2
输出:1
提示:
- 树中节点数目在范围
[2, 10^5]
内; -10^9 <= Node.val <= 10^9
;- 所有
Node.val
互不相同
; p != q
;p
和q
均存在于给定的二叉树中。
# 方法:后序遍历
- 解决这道题的思想就是「后序遍历」:需要等左右子树都遍历完成以后,综合左右子树传递上来的结果,决定当前结点向上传递什么信息;
- 通过这道问题,请大家重视「后序遍历」这个非常重要的思想(或者说解决问题的方法);
- 具体讲解请见上方的视频题解(选择快速播放,不影响理解),视频来自今年 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 来源:算法吧 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。