1. 二叉树最近公共祖先问题概述
最近公共祖先(Lowest Common Ancestor, LCA)是树结构中的一个经典问题,在算法面试和实际工程中都有广泛应用。给定一棵二叉树和两个节点p、q,我们需要找到它们深度最大的共同祖先节点。这个问题看似简单,但蕴含着对树结构的深刻理解和递归算法的精妙运用。
理解LCA问题需要掌握几个关键概念:
- 祖先节点的定义:若节点x位于从根节点到节点y的路径上,则x是y的祖先
- 公共祖先:同时是p和q的祖先的节点
- 最近公共祖先:所有公共祖先中深度最大的那个
这个问题在实际中有多种应用场景,比如在版本控制系统中寻找两个分支的分叉点,在DOM树中寻找两个元素的最近共同容器等。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 问题分析与解法思路
2.1 基础情况分析
在解决LCA问题时,我们需要考虑几种基本情况:
- 当p或q就是当前节点时,当前节点就是它们的LCA
- 当p和q分别位于当前节点的左右子树中时,当前节点就是它们的LCA
- 当p和q都在左子树或都在右子树时,我们需要在相应的子树中继续查找
这些基本情况构成了我们递归解法的基础逻辑框架。
2.2 递归解法原理
递归是解决树结构问题的自然方式。对于LCA问题,递归解法的核心思想是:
- 从根节点开始遍历整棵树
- 如果当前节点是p或q,则返回当前节点
- 递归地在左右子树中查找p和q
- 如果左右子树都返回非空结果,说明当前节点就是LCA
- 如果只有一边返回非空,则返回该边的结果
这种解法的时间复杂度是O(n),因为最坏情况下需要遍历所有节点。空间复杂度也是O(n),主要是递归栈的空间消耗。
3. 不同树结构的解法实现
3.1 普通二叉树的解法
对于普通二叉树,我们需要完整地遍历整棵树来寻找LCA。以下是完整的C++实现:
cpp复制/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*
