【中等】力扣算法题解析LeetCode235:二叉搜索树的最近公共祖先

关注文末推广名片,即可免费获得本题测试源码

题目来源:LeetCode235:二叉搜索树的最近公共祖先

问题抽象: 给定一个二叉搜索树(BST)的根节点 root 和树中两个节点 pq,要求找到 pq最近公共祖先(LCA) 节点(即深度最大的共同祖先),需满足以下核心需求:

  1. LCA 定义

    • 祖先关系:节点 xpq 的祖先需满足:
      • pq 均在 x 的子树中(或 x=px=q);
    • 最近性x 是所有满足条件的节点中深度最大者(离 pq 最近)。
  2. 输入约束

    • 节点数 ∈ [2, 10^4](保证 pq 存在且不同);
    • 节点值唯一(含负整数),且满足 BST 性质(左子树值 < 根值 < 右子树值);
    • pq 为树中实际存在的节点(非值拷贝)。
  3. BST 特性利用

    • 值比较替代路径搜索:根据 p.valq.val 与当前节点值的相对位置确定 LCA 方向:
      • p.valq.val 小于 当前节点值 → LCA 在左子树;
      • p.valq.val 大于 当前节点值 → LCA 在右子树;
      • 否则当前节点即为 LCA。
  4. 计算要求

    • 时间复杂度 O(h)h 为树高,最坏 O(n) 当树退化为链表);
    • 空间复杂度 O(1)(迭代实现,仅用指针遍历);
    • 禁止存储父指针或额外路径空间。
  5. 边界处理自身为祖先:若 pq 的祖先(或反之),则 p(或 q)即为 LCA

输入:BST 根节点 root;树中节点 pqp ≠ q)。
输出:节点(pq 的最近公共祖先)。


解题思路

核心思路:利用二叉搜索树的性质(左子树所有节点值 < 根节点值 < 右子树所有节点值):

  1. 从根节点开始遍历
    • 若当前节点值同时大于 pq 的值,说明最近公共祖先在左子树,继续向左遍历。
    • 若当前节点值同时小于 pq 的值,说明最近公共祖先在右子树,继续向右遍历。
    • 否则,当前节点即为最近公共祖先(包括两种情况):
      • pq 分别在当前节点的两侧。
      • 当前节点是 pq 之一(符合“节点可以是自身祖先”的定义)。
  2. 迭代优化:使用循环代替递归,避免栈空间开销,降低内存消耗。

时间复杂度:O(h),其中 h 是树的高度。
空间复杂度:O(1),仅使用常数级额外空间。


代码实现(Java版)🔥点击下载源码

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        // 确保 p 是较小节点,q 是较大节点,简化后续比较
        int minVal = Math.min(p.val, q.val);
        int maxVal = Math.max(p.val, q.val);
        
        // 从根节点开始迭代
        TreeNode current = root;
        while (current != null) {
            if (current.val > maxVal) {
                // 当前值大于 maxVal,说明 p 和 q 都在左子树
                current = current.left;
            } else if (current.val < minVal) {
                // 当前值小于 minVal,说明 p 和 q 都在右子树
                current = current.right;
            } else {
                // 当前节点值在 [minVal, maxVal] 区间内,即为最近公共祖先
                break;
            }
        }
        return current;
    }
}

代码说明

  1. 初始化
    通过 minValmaxVal 确定 pq 的值区间,避免后续重复比较。
  2. 迭代过程
    • 若当前节点值大于 maxVal,向左子树移动(pq 均在左子树)。
    • 若当前节点值小于 minVal,向右子树移动(pq 均在右子树)。
    • 否则,当前节点值在区间内,即为结果。
  3. 终止条件
    循环结束时 current 指向最近公共祖先节点。

提交详情(执行用时、内存消耗)

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

达文汐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值