剑指 Offer 68 - II. 二叉树的最近公共祖先

题目:

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

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

题解:

要在二叉树中找到对应结点的最近祖先结点,且两个结点是不同的、必存在树的。这需要考虑结点分布的情况,若两个结点都在左子树或右子树上,那么只需要返回存在的第一个结点即可(题目要求),若分别在左右子树上,需要找到首先分叉的结点,这里可以考虑使用两个计数器,分别用于遍历的结点(临时计数器)和总计计数器:

    private int k = 2;
    private  TreeNode res;
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
       k = 2;
       dfs(root,p,q);
       return res;
    }

    public void dfs(TreeNode node,TreeNode p,TreeNode q){
        if(node == null) return;
        int kOld = k;//记录每一个结点的k
        if(node.val == p.val || node.val == q.val) k--;
        dfs(node.left,p,q);
        dfs(node.right,p,q);
        /**
         * 找到两个结点,回退后遇到的第一个kOld为2的结点为最近祖先节点,res==null是为了防止回退过程中,改变res的值
         */
        if(kOld == 2 && k == 0 && res == null){
            res = node;
        }
    }

第二种方法:

        if(root == null || root == p || root == q) return root;//找到p或q,返回这个结点,找不到则返回null

        /**
         * 查找pq是否都在左边或者右边,且返回值一定是第一个出现在左边或者右边的结点
         * 如果同在左边或者右边,则找到第一个就可以
         */
        TreeNode pqLeft = lowestCommonAncestor(root.left,p,q);
        TreeNode pqRight = lowestCommonAncestor(root.right,p,q);

        if(pqLeft == null) return pqRight;//都不在左子树,则必在右边
        if(pqRight == null) return pqLeft;//都不在右子树,则必在左边

        return root;//不全在左边,也不全在右边,返回root

具体可以看一下b站的视频:B站视频链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值