0%

LeetCode 236. 二叉树的最近公共祖先

题目描述

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

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

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

img

示例 1:

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

示例 2:

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

题解

递归法

思路

  • 深度遍历所有节点。如果找到节点pq,说明这条子孙链上出现了节点pq
  • 当这个节点的左右子节点能分别找到节点pq,说明这个节点是最近公共祖先(LCA: Lowest Common Ancestor)

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// C++
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if (!root || !p || !q) {
return root;
}
if ((root == p) || (root == q)) {
return root;
}
auto left = lowestCommonAncestor(root->left, p, q); // 在左子节点中找到了lca(最近公共祖先)或 p/q中的一个节点
auto right = lowestCommonAncestor(root->right, p, q); // 在右子节点找到
if (left && right) {
return root; // 同时满足,说明p/q分别属于这个节点左右子节点的某个子孙节点
}
return left ? left : right;
}