算法:二叉树的公共祖先

题目

函数:

java 复制代码
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
 
    }
}

思路

  1. 定义递归函数的含义

    • 我们设计一个递归函数,比如 find(node, p, q)
    • 这个函数的任务不是直接返回最终答案,而是返回它在以 node 为根的子树中的查找结果
    • 查找结果有三种可能:
      a. 在这棵子树里找到了 p
      b. 在这棵子树里找到了 q
      c. 在这棵子树里同时找到了 pq(这意味着我们已经找到了LCA)。
      d. 什么都没找到。
  2. 后序遍历的思考方式

    • 要判断当前节点 nodep, q 的关系,我需要先知道我的左子树右子树的查找结果。这就是典型的"后序遍历"思维------先处理子节点,再处理父节点。
  3. 在当前节点 node 做出决策

    • 我向我的左子树 node.left 发出询问:find(node.left, p, q),得到左边的查找结果 left_result
    • 我向我的右子树 node.right 发出询问:find(node.right, p, q),得到右边的查找结果 right_result
    • 现在,我作为 node 节点,手握 left_resultright_result 这两条信息,开始分析:
      • 情况A:左边找到了一个,右边也找到了一个 (left_result 找到了p, right_result 找到了q,或者反之)。
        • 这意味着什么?pq 分别位于我的两侧!那我 node 不就是它们相遇的第一个节点吗?我就是它们的最近公共祖先!问题解决,我就是答案。
      • 情况B:左边找到了 p 或 q,但右边什么也没找到
        • 左子树返回的结果 left_result 其实就是它那边找到的LCA或者目标节点p或q,我只需要把这个结果继续向上传递给我的父节点就行。
      • 情况C:右边找到了,左边没找到
        • 和情况B同理,我把 right_result 向上汇报。
      • 情况D:我自己 (node) 就是 p 或者 q
        • 根据定义,一个节点可以是自己的祖先。那我就是我这棵子树里能找到的最高的目标节点。我直接把自己作为结果向上汇报,都不用再问我的子树了。

代码

java 复制代码
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root==null) return null;
        if(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 root;
        else if(left!=null) return left;
        else if(right!=null) return right;
        else return null; 
    }
}
相关推荐
devilnumber1 小时前
Java 递归算法 详解 + 核心要点 + 实战运用 + 避坑指南
java·开发语言·算法
‎ദ്ദിᵔ.˛.ᵔ₎3 小时前
双指针、滑动窗口、前缀和、二分查找 算法
算法
顾北顾3 小时前
多头注意力机制
人工智能·深度学习·算法
H178535090963 小时前
SolidWorks_基于草图的实体特征20_特征错误排查
算法·3d建模·solidworks
hujinyuan201603 小时前
2025年12月中国电子学会青少年机器人技术等级考试试卷(二级) 真题+答案
人工智能·算法·机器人
bIo7lyA8v4 小时前
算法复杂度评估的实验统计方法与可视化的技术8
算法
李老师讲编程4 小时前
中国电子学会图形化2020.12月Scratch三级考级题
算法·scratch·信息学奥赛·图形化编程·scratch素材
退休倒计时5 小时前
【每日一题】LeetCode 53. 最大子数组和 TypeScript
数据结构·算法·leetcode·typescript
旖-旎5 小时前
FloodFill(图像渲染)(1)
c++·算法·深度优先·力扣