题目
- 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
![]()
题解:递归
- 前序遍历,判断当前节点是不是p或q,是的话返回当前节点,递归左子树和右子树,如果都有返回值则当前root就是最近公共祖先。
var lowestCommonAncestor = function(root, p, q) {
// 基础条件:如果根节点为空,返回 null
if (root === null) return null;
// 如果当前节点是 p 或 q,直接返回当前节点
if (root === p || root === q) return root;
// 递归搜索左子树和右子树
const left = lowestCommonAncestor(root.left, p, q);
const right = lowestCommonAncestor(root.right, p, q);
// 如果左子树和右子树都找到了 p 或 q,当前节点是最近公共祖先
if (left && right) return root;
// 否则返回找到的非 null 值,处理p为根节点的情况
return left ? left : right;
};
- 对于示例2,题目明确了给出的pq是树的两个节点,所有可以找到一个根满足的情况返回,即使没有进入找到q在子树的情况。我们详细看一下示例2的执行过程:
| 步骤 |
当前节点 |
返回值 |
说明 |
| 1 |
3 |
- |
当前节点不为null,不等于pq,继续递归。 |
| 2 |
5 |
5 |
递归左,当前节点是 5,等于p,返回 5(p)。 |
| 3 |
1 |
- |
递归右,当前节点是 1,不为null,不等于pq,继续递归。 |
| 4 |
null |
null |
左子树为空,返回 null。 |
| 5 |
8 |
- |
递归右,当前节点是 8,不为null,不等于pq,继续递归。 |
| 6 |
null |
null |
递归左,左子树为空,返回 null。 |
| 7 |
null |
null |
递归右,右子树为空,返回 null。 |
| 8 |
8 |
null |
左右子树都返回 null,返回 null。 |
| 9 |
1 |
null |
左子树返回 null,右子树返回 null,返回 null。 |
| 10 |
3 |
5 |
左子树返回 5,右子树返回 null,返回 5。 |