一、题目描述:
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 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 。
引自:leetcode-cn.com/problems/lo…
题目链接:236. 二叉树的最近公共祖先
二、思路分析:
-
首先如果根节点为空或 根节点和p 或 根节点和q 是同一结点 直接返回 根结点;
-
考虑用递归方式查看 p 和 q 在根结点的左子树中还是右子树中;
-
主要考虑 3 种 情况
假设使用下方的这棵二叉树;
1
/ \
2 3
/ \ \
4 5 6
- 情况1:
如果 root、p、q 分别为 1、2、3;
那么可见 root 如果和 p 或q 是同一结点,就直接返回 root 根结点即可;
- 情况2:
如果 root、p、q 分别为 1、5、6
那么第1次调用 lowestCommonAncestor leftNode 为:2
那么第1次调用 lowestCommonAncestor rightNode 为:3
然后又变成了情况1 最终会返回 root 根结点
- 情况3:
如果 root、p、q 分别为 1、3、6;(p,q 均在 root 的左子树和右子树是一个逻辑)
那么 root 的左子树方向调用 lowestCommonAncestor 终究会得到 leftNode 为 nil ;
然后 root 的左子树方向调用 lowestCommonAncestor 终究会得到 rightNode 为结点3;
我们返回rightNode 3 即可。
三、AC 代码:
class Solution {
func lowestCommonAncestor(_ root: TreeNode?, _ p: TreeNode?, _ q: TreeNode?) -> TreeNode? {
// 如果根节点为空或 根节点和p 或 根节点和q 是同一结点 直接返回 根结点
if (root == nil || root === p || root === q) {
return root;
}
let leftNode : TreeNode? = lowestCommonAncestor(root?.left, p, q);
let rightNode : TreeNode? = lowestCommonAncestor(root?.right, p, q);
if (leftNode == nil) {
return rightNode;
}
if (rightNode == nil) {
return leftNode;
}
return root;
}
}
四、参考学习网址
本文正在参与「掘金 3 月闯关活动」, 点击查看 活动详情
