二叉树中最低的共同祖先。超出时限

时间:2016-01-25 23:36:11

标签: java data-structures binary-tree lowest-common-ancestor

我已经编写了这个解决方案,用于查找二叉树的LCA。它会在较大的输入上超出时间限制。有人可以指出这段代码中的问题。这个问题来自Leetcode OJ。

public class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
    if(root == null){
        return null;
    }if((p.val == root.val) || (q.val == root.val)){
        return root;
    } 
    if(root.left == null && root.right == null){
        return null;
    }
    boolean leftChildP = isLeftChild(root,p);
    boolean leftChildQ = isLeftChild(root,q);

    if(isRightChild(root,p) && isLeftChild(root,q)){
        return root;
    }if(isRightChild(root,q) && isLeftChild(root,p)){
        return root;
    }
    if(leftChildP && leftChildQ){
            return lowestCommonAncestor(root.left,p,q);
    }
    return lowestCommonAncestor(root.right,p,q);}


private boolean isLeftChild(TreeNode root, TreeNode node){
    return isChild(root.left,node);
}


private boolean isRightChild(TreeNode root, TreeNode node){
     return isChild(root.right,node);   
}


private boolean isChild(TreeNode parent, TreeNode child){
    if(parent == null){
        return false;}
    if(parent.val == child.val){
        return true;
    }return (isChild(parent.left,child) || isChild(parent.right,child));
}}

2 个答案:

答案 0 :(得分:1)

递归lowestCommonAncestor正在调用递归isChild ...非常简短的检查表明它是O(n ^ 2)。这将耗费时间......

尝试构建所有祖先p的哈希集 - 这可能会花费你O(n),但通常是O(logn)。然后从q寻找一个共同的祖先。假设hashset中的查找花费O(1),这将再次花费你 - O(n),但通常是O(logn)。

你最终会得到O(logn)的典型复杂性 - 这更好......

答案 1 :(得分:1)

您编写的代码具有复杂度O(n ^ 2)。

您可以通过两种方式在O(n)中找到LCA

1。)将根存储到节点路径(在ArrayList中或可以使用hashset)用于两个节点(p和q)。现在开始比较从root开始的两个路径中的节点(直到LCA应该匹配p和q的路径),因此恰好在路径中发生不匹配之前的节点将是LCA。该解决方案应该在O(n)中工作。

2.)其他解决方案的假设是,如果p和q中只有一个节点退出树,那么你的lca函数将返回该节点。 这是你可以做的代码

public BinaryTreeNode<Integer> lca(BinaryTreeNode<Integer> root, int data1, int data2){ if(root == null){ return null; } if(root.data == data1 || root.data == data2){ return root; } BinaryTreeNode<Integer> leftAns = lca(root.left, data1 , data2); BinaryTreeNode<Integer> rightAns = lca(root.left, data1 , data2); / // If you are able to find one node in left and the other in right then root is LCA if(leftAns!= null && rightAns != null){ return root; } if(leftAns!=null){ return leftAns; } else{ return rightAns; } }

这也具有时间复杂度O(n)