递归(一)二叉树的最近公共祖先
问题描述
给定一个二叉树,找到该树中两个指定节点的最近公共节点。
例如,对于给定的二叉树:
现在需要查找节点 和 的公共祖先节点,应当返回节点 。
说明:
-
在输入的二叉树中,所有的节点值都是唯一的
-
要查找的节点 和 均存在于给定的二叉树中
解决思路
思路比较简单,只要遍历整个二叉树,然后检查正在遍历的节点是否同时包含 和 ,由于约束条件的存在,因此第一个同时包含 和 的节点必定是 和 两个节点的最近公共祖先
这里比较麻烦的地方在于情况的分析,如下:
-
如果当前遍历的节点的 和 都不包含 和 ,那么说明这两个节点不存在于当前节点的左右子树中,这种情况下应该返回
-
如果当前遍历的节点的 和 都含有一个待搜索的节点,那么说明 和 分布在当前遍历的节点的左右两侧,这种情况下当前的节点就是 和 的最近公共祖先节点
-
如果当前遍历的节点的 不包含 和 的任意一个节点,但是 至少包含 和 的一个节点,那么这种情况下需要进一步分析
-
和 的其中一个节点在 子树中,那么说明当前遍历的节点中包含 或
-
和 两个节点都在 子树中,那么此时的 节点就是 、 两个节点的最近公共祖先
-
当 不为空,但是 为空时,和第三种情况类似
实现
具体实现代码如下:
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.val == p.val || root.val == q.val)
return root;
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);
if (left == null && right == null) return null; // 对应第一种情况
if (left == null) return right; // 对应第三种情况
if (right == null) return left; // 对应第四种情况
return root; // 对应第二种情况
}
}
复杂度分析:
-
时间复杂度:由于需要遍历节点,在最差的情况下需要遍历所有的节点,因此时间复杂度为
-
空间复杂度:忽略由于递归带来的栈空间消耗,空间复杂度为
参考:
[1] https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix