每日一题:二叉树的最近公共祖先

84 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

二叉搜索树可以通过其特性(值的大小限制)来找公共祖先。

那么对于一般的二叉树没有这个值的限制我们应该怎么去查找公共祖先?

一、题目描述:

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

示例:

image-20220324191022661.png

输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出:3
解释:节点 5 和节点 1 的最近公共祖先是节点 3 。
​
输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
输出:5
解释:节点 5 和节点 4 的最近公共祖先是节点 5 。因为根据定义最近公共祖先节点可以为节点本身。

二、思路分析:

  1. 在当前节点的左子树找p或者q,如果都没有p和q,那就在节点的右子树寻找
  2. 然后右边寻找p或q,若两个节点都没有,则去左边找
  3. 如果两边都找到了p或q(一个是左,一个是右),那就说明当前节点就是两个节点的公共祖先。

三、代码实现:

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} root
 * @param {TreeNode} p
 * @param {TreeNode} q
 * @return {TreeNode}
 */
var lowestCommonAncestor = function(root, p, q) {
    // find P or Q: null返回自己,找到了p或者q就返回自己
    if (root==null || root==p || root== q) {
        return root;
    }
    // left就是左边递归找的结果,right为递归右边找的结果
    const left = lowestCommonAncestor(root.left, p, q)
    const right = lowestCommonAncestor(root.right, p, q)
    // 如果左边q、p都没找到那就返回right在right找
    if(left==null) {
        return right
    }
    // 如果右边两个节点都没找到,那就去left找
    if (right==null){
        return left
    }
    // 若left和right都不为空,说明各找到一个,公共祖先为root
    return root
};