练习分享---在二叉树中找到两个节点的最近公共祖先

题目描述:

给定一棵二叉树(保证非空)以及这棵树上的两个节点对应的val值 o1 和 o2,请找到 o1 和 o2 的最近公共祖先节点。

数据范围:1 \le n \le 10001≤n≤1000,树上每个节点的val满足 0<val \le 1000<val≤100

要求:空间复杂度 O(1)O(1),时间复杂度 O(n)O(n)

注:本题保证二叉树中每个节点的val值均不相同。

如当输入[3,5,1,6,2,0,8,#,#,7,4],5,1时,二叉树{3,5,1,6,2,0,8,#,#,7,4}如下图所示:

   对于该题,我们可以使用HashMap对数据进行存储,在存储时因为题目需要找到公共祖先,所以我们可以对key-value->赋值为 该节点的值-父节点的值。然后对树进行层序遍历,通过层序遍历和HashMap的配合将树的结点都记录下来,但是我们只需要找到o1和o2两个值对应结点的公共祖先结点,所以我们并不需要将整个树都记录下来,所以我们的终止条件就是当HashMap中已经存储了key(o1)和key(o2)。

   截止现在,我们已经在map中存储了包含o1和o2值的结点,那么在接下来我们需要去寻找o1和o2和公共祖先。在map中我们已经存储了o1和o2的祖先结点值,所以接下来我们只需要将其中o1或者o2其中一个的所有祖先结点值记录下来,然后再拿o2的祖先结点值和o1的所有祖先结点值作比较,如果o2的某个祖先结点值和o1中的某个祖先结点值相同,那么此时o2的值就是他们公共祖先结点的值,该结点就是最近的公共祖先结点。

  具体的代码实现如下:

    public int find(TreeNode root, int o1, int o2) {
        HashMap<Integer,Integer> map = new HashMap<>();
        LinkedList<TreeNode> list = new LinkedList<>();
        list.offer(root);
        map.put(root.val,-1);
        while(!map.containsKey(o1) || !map.containsKey(o2)){
            TreeNode node = list.poll();
            if(node.left != null){
                list.offer(node.left);
                map.put(node.left.val,node.val);
            }
            if(node.right != null){
                list.offer(node.right);
                map.put(node.right.val,node.val);
            }
        }
        HashSet<Integer> set = new HashSet<>();
        while(map.containsKey(o1)){
            set.add(o1);
            o1 = map.get(o1);
        }
        while(!set.contains(o2)){
            o2 = map.get(o2);
        }
        return o2;

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值