LeetCode 236 题解

 

 

import common.TreeNode;

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

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

例如,给定如下二叉树:  root = [3,5,1,6,2,0,8,null,null,7,4]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/er-cha-shu-de-zui-jin-gong-gong-zu-xian-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
 * <pre>
 * Modify Information:
 * Author        Date          Description
 * ============ =========== ============================
 * wangm          2020年5月11日    Create this file
 * </pre>
 * 
 */

public class LeetCode236 {
    
    /**
     * 思路1: 如果节点有父节点指针的话,这样你能保留这个路径,LCA  lowestCommonAcesstor 找最短公共路径
     * 思路2: 思路惊奇:  root 节点, 如果 q 节点在 左子树,p 在root 的右子树,那么 root 就是 q p 公共父亲。
     *              如果左子树没找到 p, 也没找到 q  返回的是个 null, 那么 就在右子树上 
     *              如果右子树没找到 p, 也没找到 q  返回的是个 null,那么就在左子树上
     * @param root
     * @param p
     * @param q
     * @return
     */
    
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        // 如果 root 为 null 那么返回 null
        // 如果  p 或者 q 就已经在根节点上了,那最短路径父亲就是 q 或者 p
        if(root == null || root == p || root == q) return root;
        // 从root 节点的左子树开始找
        TreeNode left = lowestCommonAncestor(root.left, p, q);
        // 从 root 节点的右子树开始找
        TreeNode right = lowestCommonAncestor(root.right, p, q);
        
        // 如果有一个时刻,发现 root 节点的左子树包含p/q  右子树包含  q/p  那么 root 就是最短父亲。
        if(left != null && right != null){
            return root;
        }
        // 如果有一个时刻,发现 右子树没找到 p/q,那么 父亲肯定在 左子树上找到
        if(right == null){
            return left;
        }
        // 如果有一个时刻,发现左子树上 没找到 p/q,那么 父亲肯定在 右子树上找到
        return right;
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub

    }

}

 

wangxiaoming CSDN认证博客专家 架构 Spring Boot Redis
博客是很好的总结和记录工具,如果有问题,来不及回复,关注微信公众号:程序员开发者社区,获取我的联系方式,向我提问,也可以给我发送邮件,联系 1275801617@qq.com
©️2020 CSDN 皮肤主题: Age of Ai 设计师: meimeiellie 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值