leetcode 236. Lowest Common Ancestor of a Binary Tree-二叉树共同祖先|深度遍历|递归|非递归

原题链接:236. Lowest Common Ancestor of a Binary Tree

【思路-Java】dfs|递归实现

本题是二叉树的深度遍历的典型应用,基础还是二叉树的遍历。

以根节点为起点,往左右分支上寻找,如果找到了 p 或 q 节点,则返回该节点。否则,继续向叶子节点寻找,假想一下,如果一直递归到 null 还是找不到该节点,那么说明这个分支上不存在该节点。

public class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        //如果找到 p 或者 q 那么就没有必要接着递归,因为共同祖先只可能是该节点或该节点祖先
        //如果 root 为空了,说明这条路径上不可能有 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;  //说明 p 和 q 是分布在 root 两侧,返回即可
        if(left != null) return left;  //说明在 left 分支上找到 p 或 q 节点,返回即可
        return right;  //否则返回 right
    }
}
31 / 31  test cases passed. Runtime: 13 ms  Your runtime beats 30.43% of javasubmissions.

【思路2-Java】bfs|非递归实现

需要借用一些数据结构,hashmap 中存放节点及其父节点。采用队列广度遍历,直到 p 和 q 的父亲节点都找到为止,然后找到公共父节点,效率不高,供大家拓宽思路:

public class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        HashMap<TreeNode, TreeNode> parent = new HashMap<>();
        parent.put(root, null);
        Queue<TreeNode> queue = new LinkedList<>();
        queue.add(root);
        while(!parent.containsKey(p) || !parent.containsKey(q)) {  //找到 p 和 q 的父节点
            root = queue.poll();
            if(root != null) {
                parent.put(root.left, root);
                parent.put(root.right, root);
                queue.add(root.left);
                queue.add(root.right);
            }
        }
        HashSet<TreeNode> set = new HashSet<>();
        while(p != null) {  //将 p 的所有父节点放入 set 中
            set.add(p);
            p = parent.get(p);
        }
        while(!set.contains(q)) {  //找到公共父节点就返回
            q = parent.get(q);
        }
        return q;
    }
}
31 / 31  test cases passed. Runtime: 36 ms  Your runtime beats 5.38% of javasubmissions.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值