Java_[最近公共祖先]两种题型详解

       在求解“最近公共祖先”的问题时,会遇到两种问题,一种是基于树状结构下求公共祖先、一种是一组带有连续编号的数字在树的结构下进行布局。

 

       题目一:

      将一棵无穷大满二叉树的结点按根结点一层一层地从左往右编号,根结点编号为1。现给定a,b为两个结点。设计一个算法,返回a、b最近的公共祖先的编号。注意其祖先也可能是结点本身。

 

https://www.nowcoder.com/practice/70e00e490b454006976c1fdf47f155d9?tpId=8&&tqId=11017&rp=1&ru=/activity/oj&qru=/ta/cracking-the-coding-interview/question-ranking

 

      题目二:

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

 

https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/

看完本章题解可以点开两个题目的链接试试~~~

 

题目一解析:

        若根节点为1,那么p和q的根节点判定可以分为两种情况。

        1.若p == q,那么p和q的最近公共祖先则可以表示为p和q中任意一个值,表明此时已经找到该两个节点的最近公共祖先,此时函数调用结束。

        2.若p > q或者q > q,那么需要每次挑出p和q中的最大值,进行取模2运算,直到回归到第一种情况,返回最近共祖祖先值,调用函数结束。

 

        Java解决函数代码如下:

import java.util.*;

public class LCA {
    public int getLCA(int a, int b) {
        // write code here
        while(a != b) {//每次取最大值进行模2运算,直至a和b两值相同
            if(a > b) {
                a /= 2;
            } else {
                b /= 2;
            }
        }
        return a;
    }
}

 

        题目二解析:

           在每个节点的判定节点时,可分为如下情况:

           1.此时根节点为null或者左节点或者右节点为null时,返回null,表明两节点无最近公共祖先,结束此次函数调用。

           2.此时左节点为null且右节点不为null时,返回右节点的值。

           3.此时右节点为null且左节点不为null时,返回左节点的值。

           4.此时左节点和右节点都不为null时,返回左右节点的根节点值。

           

       每次递归查询树状结构的左子树和右子树,通过前面的4种条件判定当前最近公共祖先的值,并返回结果。

 

            Java解决问题代码如下:

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root == null) return null;
        if(p == null || q == null) return null;
        if(root == p || root == q) return root;
        TreeNode leftNode = lowestCommonAncestor(root.left,p,q);
        TreeNode rightNode = lowestCommonAncestor(root.right,p,q);
        if(leftNode != null && rightNode == null) return leftNode;
        if(leftNode == null && rightNode != null) return rightNode;
        if(leftNode != null && rightNode != null) return root;
        return null;
    }
}

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java二叉树最近公共祖先可以通过递归来解决。首先,我们需要定义一个TreeNode类表示二叉树的节点,其中包含值和左右子节点的引用。下面是一个示例代码: ```java class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int val) { this.val = val; } } ``` 接下来,我们可以实现一个递归函数来找到最近公共祖先: ```java public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { // 判断当前节点是否为空或者等于p或q if (root == null || root == p || root == q) { return root; } // 在左子树中寻找最近公共祖先 TreeNode left = lowestCommonAncestor(root.left, p, q); // 在右子树中寻找最近公共祖先 TreeNode right = lowestCommonAncestor(root.right, p, q); // 如果左子树和右子树都找到了最近公共祖先,则当前节点就是最近公共祖先 if (left != null && right != null) { return root; } // 如果只有左子树找到了最近公共祖先,则返回左子树的结果 if (left != null) { return left; } // 如果只有右子树找到了最近公共祖先,则返回右子树的结果 if (right != null) { return right; } // 如果左右子树都没有找到最近公共祖先,则返回null return null; } ``` 这个递归函数的基本思路是: - 当前节点为空或者等于p或q时,直接返回当前节点; - 在左子树中寻找最近公共祖先; - 在右子树中寻找最近公共祖先; - 如果左子树和右子树都找到了最近公共祖先,则当前节点就是最近公共祖先; - 如果只有左子树找到了最近公共祖先,则返回左子树的结果; - 如果只有右子树找到了最近公共祖先,则返回右子树的结果; - 如果左右子树都没有找到最近公共祖先,则返回null。 你可以调用这个函数来找到二叉树中任意两个节点的最近公共祖先
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值