题目描述
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
提示:
- 树中节点数目在范围 [2, 105] 内。
- -109 <= Node.val <= 109
- 所有 Node.val 互不相同 。
- p != q
- p 和 q 均存在于给定的二叉树中。
题解
- 后序遍历,自底向上。用
left
接受左子树的返回值,right
接受右子树的返回值 - 遇到p返回p,遇到q返回q
left == null
时,返回right
,right == null
时候返回left
,都不为空时,返回根节点
(最近公共祖先)
分析一下代码:
- 分为两种情况 :
- 一、其中一个节点是另一个节点的祖先: 假设q是p的父节点(最近公共祖先就是q),后续遍历先遇到的是p,此时返回的是p。当遍历到q时,返回值更换为q,由于其他路径上没有pq了,所以其他路径的返回值都为
null
,这个q节点就会一直返回到最上层,得到结果。 - 二、两个节点有公共的祖先:当遇到pq的最近公共祖先,此时left和right的返回值必是一个p一个q,这时会返回这个根节点,由于其他路径上没有pq了,所以其他路径的返回值都为
null
,这个根节点就会一直返回到最上层,得到结果。
- 一、其中一个节点是另一个节点的祖先: 假设q是p的父节点(最近公共祖先就是q),后续遍历先遇到的是p,此时返回的是p。当遍历到q时,返回值更换为q,由于其他路径上没有pq了,所以其他路径的返回值都为
代码:
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == p || root == q || root == null) return root;
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);
if (left == null) return right;
if (right == null) return left;
//left、right都不为空,此时root为最近公共祖先
return root;
}
}