二叉树中的最低公共祖先。超过时间限制
Lowest Common Ancestor in a Binary Tree. Time Limit Exceeded
我已经写了这个解决方案来寻找二进制的 LCA Tree.It 给出了在更大的输入上超过的时间限制。有人可以指出这段代码中的问题吗?本题来自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));
}}
递归 lowestCommonAncestor
正在调用递归 isChild
...非常简短的检查表明它是 O(n^2)。会很费时间...
尝试构建 p
的所有祖先的哈希集 - 这可能会花费 O(n),但通常为 O(logn)。然后从 q
向上遍历寻找一个共同的祖先。假设哈希集中的查找成本为 O(1),这将再次花费您 - O(n),但通常为 O(logn)。
您最终会得到 O(logn) 的典型复杂度 - 这更好...
你写的代码复杂度为O(n^2)。
您可以通过两种方式在 O(n) 中找到 LCA
1.) 将两个节点(p 和 q)的根存储到节点路径(在 ArrayList 中或可以使用哈希集)。现在开始比较从根开始的两条路径中的节点(直到 LCA 的路径应该匹配 p 和 q),因此路径中发生不匹配之前的节点将是 LCA。这个解决方案应该在 O(n) 中工作。
2.) 其他解决方案假设如果 p 和 q 中只有一个节点存在于您的树中,那么您的 lca 函数将 return 该节点。
这是您可以执行的代码
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)
我已经写了这个解决方案来寻找二进制的 LCA Tree.It 给出了在更大的输入上超过的时间限制。有人可以指出这段代码中的问题吗?本题来自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));
}}
递归 lowestCommonAncestor
正在调用递归 isChild
...非常简短的检查表明它是 O(n^2)。会很费时间...
尝试构建 p
的所有祖先的哈希集 - 这可能会花费 O(n),但通常为 O(logn)。然后从 q
向上遍历寻找一个共同的祖先。假设哈希集中的查找成本为 O(1),这将再次花费您 - O(n),但通常为 O(logn)。
您最终会得到 O(logn) 的典型复杂度 - 这更好...
你写的代码复杂度为O(n^2)。
您可以通过两种方式在 O(n) 中找到 LCA
1.) 将两个节点(p 和 q)的根存储到节点路径(在 ArrayList 中或可以使用哈希集)。现在开始比较从根开始的两条路径中的节点(直到 LCA 的路径应该匹配 p 和 q),因此路径中发生不匹配之前的节点将是 LCA。这个解决方案应该在 O(n) 中工作。
2.) 其他解决方案假设如果 p 和 q 中只有一个节点存在于您的树中,那么您的 lca 函数将 return 该节点。 这是您可以执行的代码
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)