算法:二叉树的公共祖先

题目

函数:

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; 
    }
}
相关推荐
业精于勤的牙1 小时前
浅谈:算法中的斐波那契数(二)
算法·职场和发展
不穿格子的程序员2 小时前
从零开始写算法——链表篇4:删除链表的倒数第 N 个结点 + 两两交换链表中的节点
数据结构·算法·链表
liuyao_xianhui2 小时前
寻找峰值--优选算法(二分查找法)
算法
dragoooon342 小时前
[hot100 NO.19~24]
数据结构·算法
Tony_yitao3 小时前
15.华为OD机考 - 执行任务赚积分
数据结构·算法·华为od·algorithm
C雨后彩虹4 小时前
任务总执行时长
java·数据结构·算法·华为·面试
风筝在晴天搁浅4 小时前
代码随想录 463.岛屿的周长
算法
一个不知名程序员www4 小时前
算法学习入门---priority_queue(C++)
c++·算法
TL滕5 小时前
从0开始学算法——第十八天(分治算法)
笔记·学习·算法