1. 题号和题目名称
- 二叉树的最近公共祖先
2. 题目叙述
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
3. 模式识别
这是一个典型的二叉树遍历问题,可通过递归的方式来解决。需要遍历二叉树,根据节点的分布情况来确定最近公共祖先。
4. 考点分析
- 二叉树的遍历,特别是后序遍历的应用。
- 递归思想的运用,通过递归函数来处理子问题。
- 对节点分布情况的判断,从而确定最近公共祖先。
5. 所有解法
- 递归解法:通过后序遍历二叉树,根据左右子树中是否包含目标节点来判断最近公共祖先。
- 存储父节点法:先遍历二叉树,记录每个节点的父节点,然后从目标节点开始向上回溯,找到第一个公共节点。
6. C 语言最优解法(递归解法)代码
#include <stdio.h>
#include <stdlib.h>
// 定义二叉树节点结构
struct TreeNode {
int val; // 节点的值
struct TreeNode *left; // 左子节点指针
struct TreeNode *right; // 右子节点指针
};
// 递归函数,用于查找最近公共祖先
struct TreeNode* lowestCommonAncestor(struct TreeNode* root, struct TreeNode* p, struct TreeNode* q) {
// 如果根节点为空,或者根节点就是 p 或 q,直接返回根节点
if (root == NULL || root == p || root == q) {
return root;
}
// 递归查找左子树中 p 和 q 的最近公共祖先
struct TreeNode* left = lowestCommonAncestor(root->left, p, q);
// 递归查找右子树中 p 和 q 的最近公共祖先
struct TreeNode* right = lowestCommonAncestor(root->right, p, q);
// 如果左子树和右子树都找到了目标节点,说明根节点就是最近公共祖先
if (left != NULL && right != NULL) {
return root;
}
// 如果左子树找到了目标节点,返回左子树的结果
if (left != NULL) {
return left;
}
// 否则返回右子树的结果
return right;
}
7. 复杂度分析
- 时间复杂度:O(n)O(n)O(n),其中 nnn 是二叉树的节点数。因为需要遍历二叉树的每个节点。
- 空间复杂度:O(h)O(h)O(h),其中 hhh 是二叉树的高度。主要是递归调用栈的空间开销,最坏情况下二叉树退化为链表,空间复杂度为 O(n)O(n)O(n)。
854

被折叠的 条评论
为什么被折叠?



