求二叉树两个节点的最近公共父节点的两种方法(java实现)

11 篇文章 0 订阅
5 篇文章 0 订阅
  • 问题描述

求二叉树两个节点的最近公共父节点。

  • 解决方案1

首先找到根节点到两个节点的路径,然后将其中一个路径加入到哈希表中,然后遍历另一个路径,在哈希表中有相同的则返回即可,代码如下:

public static TreeNode lowestCommenAncestor(TreeNode root,TreeNode p,TreeNode q){
        List<TreeNode> listP = getPath(root,p);
        List<TreeNode> listQ = getPath(root,q);
        HashSet<TreeNode> set = new HashSet<>();
        for(int i = 0;i < listP.size();i ++)
            set.add(listP.get(i));
        for (int i = 0; i < listQ.size(); i++) {
            if(set.contains(listQ.get(i)))
                return listQ.get(i);
        }
        return null;
    }

    //获取从root节点到p节点的路径
    public static List<TreeNode> getPath(TreeNode root, TreeNode p){
        List<TreeNode> list = new LinkedList<>();
        isContainsNode(root, p,list);
        return list;
    }

    //检测某个节点的孩子是否包含某个节点,并找到路径加入到List中
    public static boolean isContainsNode(TreeNode root, TreeNode p,List<TreeNode> list){
        if(root == null)
            return false;
        if(root == p){
            list.add(p);
            return true;
        }
        else if(isContainsNode(root.left,p,list) || isContainsNode(root.right,p,list)){
                list.add(root);
                return true;
            }
        return false;
    }
  • 解决方案2

直接用递归来解决,比较难想明白,但是代码非常简洁:

 public static TreeNode lowestCommenAncestor2(TreeNode root,TreeNode p,TreeNode q){
        if(root == null || root == p || root == q)
            return root;
        TreeNode left = lowestCommenAncestor2(root.left,p,q);
        TreeNode right = lowestCommenAncestor2(root.right,p,q);
        if(left != null && right != null)
            return root;
        return left != null ? left : right;
    }
  • 测试

测试代码如下:

    public static void main(String[] args) {
        //测试如下二叉树
//                   1
//                /     \
//              2         3
//            /    \    /    \
//           4      5  6      7

        TreeNode root = new TreeNode(1);
        root.left = new TreeNode(2);
        root.left.left = new TreeNode(4);
        root.left.right = new TreeNode(5);
        root.right = new TreeNode(3);
        root.right.left = new TreeNode(6);
        root.right.right = new TreeNode(7);
        //4和5的父节点
        System.out.println(lowestCommenAncestor(root,root.left.left,root.left.right).val);
        System.out.println(lowestCommenAncestor2(root,root.left.left,root.left.right).val);
        //2和7的父节点
        System.out.println(lowestCommenAncestor(root,root.left,root.right.right).val);
        System.out.println(lowestCommenAncestor2(root,root.left,root.right.right).val);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值