二叉树——二叉树的最近公共祖先

核心思路
1. 递归终止条件:

  • 如果当前节点为null,直接返回null
  • 如果当前节点就是p或q,直接返回当前节点(自己是自己的祖先)

2. 递归搜索:

  • 递归查找左子树,得到结果left
  • 递归查找右子树,得到结果right

3. 判断结果:

  • 如果left和right都不为空->当前节点就是最近公共祖先
  • 如果只有left不为空->公共祖先在左子树
  • 如果只有right不为空->公共祖先在右子树

为什么遇到 root == p 或 root == q 直接 return 当前节点?

核心逻辑:递归是向上传递找到的标记

递归函数的作用定义一定要先记住:
lowestCommonAncestor(root, p, q)

如果以 root 为根的子树中包含 p 或 q,就返回找到的那个节点
如果都不包含,返回null

场景 1:当前节点就是 p
当前节点就是 p,说明:
以它为根的子树一定包含 p
按照函数职责,直接把自己返回,向上层传递:我找到 p 了

场景 2:当前节点就是 q
同理,直接返回自己,向上层传递:我找到 q 了

代码解释

1. 节点定义: 标准二叉树节点,包含值、左孩子、右孩子
2. 递归核心:

  • 从根节点开始向下遍历
  • 只要在左、右子树中分别找到了p和q,当前节点就是它们的最近公共祖先
  • 如果只在一侧子树找到,说明两个节点都在这个子树里,继续向上返回结果

3. 时间复杂度: O(n) —— 最多遍历整棵树一次
4. 空间复杂度: O(n) —— 最多遍历整棵树一次

Java代码实现如下:

public class TreeNode {

int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }

}

class Solution {

/**
 * 查找二叉树中两个节点的最近公共祖先
 * @param root 二叉树根节点
 * @param p 目标节点1
 * @param q 目标节点2
 * @return 最近公共祖先节点
 */
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
    // 递归终止:节点为空 或 当前节点就是p/q,直接返回
    if (root == null || root == p || root == q) {
        return root;
    }
    
    // 递归查找左子树
    TreeNode left = lowestCommonAncestor(root.left, p, q);
    // 递归查找右子树
    TreeNode right = lowestCommonAncestor(root.right, p, q);
    
    // 情况1:左右子树都找到节点 → 当前节点就是LCA
    if (left != null && right != null) {
        return root;
    }
    // 情况2:左子树找到,右子树没找到 → 返回左子树结果
    else if (left != null) {
        return left;
    }
    // 情况3:右子树找到,左子树没找到 → 返回右子树结果
    else {
        return right;
    }
}

}

posted @ 2026-04-29 09:50  AlexXuu  阅读(3)  评论(0)    收藏  举报