手撸算法-两个子节点的父节点

牛客原题

描述

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

示例1

输入:
[3,5,1,6,2,0,8,#,#,7,4],5,1
返回值:
3

解法一

  • 1,使用层序遍历,直到找到两个结点为止
  • 2,层序遍历过程中,将子节点与父节点组成的键值对保存在Map中
  • 3,遍历Map,将o1的所有父节点保存到集合中List中
  • 4,遍历Map,逐个判断o2的父节点是否存在于o1的父节点集合中,如果存在,则二者有相同的父节点

思考:如何保证最后找到的是最近的父节点

因为对于o2的遍历是从下向上的,每次判断的都是离o2最低的父节点,则找出来的也是二者的最近父节点

    public int lowestCommonAncestor (TreeNode root, int o1, int o2) {
    
    
        // write code here
        // 1,遍历找到o1和o2
        // 2,找到o1的所有父节点集合
        // 3,判断o2的父节点是否存在于o1的父节点集合
        Queue<TreeNode> queue = new ArrayDeque<>();
        queue.add(root);
        Map<Integer,Integer> nodes = new HashMap<>();
        nodes.put(root.val,Integer.MAX_VALUE);
        while(queue.size() > 0 && (!nodes.containsKey(o1) || !nodes.containsKey(o2))) {
    
    
            TreeNode parent = queue.poll();
            if (parent.left != null) {
    
    
                queue.add(parent.left);
                nodes.put(parent.left.val, parent.val);
            } 
            
            if (parent.right != null) {
    
    
                queue.add(parent.right);
                nodes.put(parent.right.val, parent.val);
            }
        }
        
        List<Integer> parents = new ArrayList<>();
        
        // 结点的父节点可能是结点本身,所以o1自身也要放入结点的父节点集合中
        while (o1 != Integer.MAX_VALUE) {
    
    
            parents.add(o1);
            o1 = nodes.get(o1);
        }
        
        while (!parents.contains(o2)) {
    
    
            o2 = nodes.get(o2);
        }
        
        return o2;
    }

猜你喜欢

转载自blog.csdn.net/epitomizelu/article/details/120053107
今日推荐