-
-
Save deyindra/a9a3c4028c6fd99b346abc294e5ec12f to your computer and use it in GitHub Desktop.
Given 2/N distinct Nodes of the BinaryTree (They may or may not exist) find Lowest Common Ancestor of the all these nodes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** Tree Node class **/ | |
public class TreeNode<E> { | |
private E data; | |
private TreeNode<E> left; | |
private TreeNode<E> right; | |
public TreeNode(E data) { | |
this.data = data; | |
} | |
public TreeNode<E> addLeft(TreeNode<E> left){ | |
this.left = left; | |
return this; | |
} | |
public TreeNode<E> addRight(TreeNode<E> right){ | |
this.right = right; | |
return this; | |
} | |
public TreeNode<E> getLeft() { | |
return left; | |
} | |
public TreeNode<E> getRight() { | |
return right; | |
} | |
public E getData() { | |
return data; | |
} | |
@Override | |
public boolean equals(Object o) { | |
if (this == o) return true; | |
if (o == null || getClass() != o.getClass()) return false; | |
TreeNode<?> treeNode = (TreeNode<?>) o; | |
if (data != null ? !data.equals(treeNode.data) : treeNode.data != null) return false; | |
return true; | |
} | |
@Override | |
public int hashCode() { | |
return data != null ? data.hashCode() : 0; | |
} | |
@Override | |
public String toString() { | |
return data.toString(); | |
} | |
} | |
/** For 2 distinct nodes **/ | |
public static <E> TreeNode<E> LCA(TreeNode<E> root, final TreeNode<E> first, final TreeNode<E> second){ | |
BitSet booleanSets = new BitSet(2); | |
booleanSets.set(0,2,false); | |
TreeNode<E> lca = LCA(root,booleanSets,first,second); | |
if(booleanSets.get(0) && booleanSets.get(1)) | |
return lca; | |
else { | |
return null; | |
} | |
} | |
/** for N Distinct Nodes**/ | |
public static <E> TreeNode<E> LCAMulti(TreeNode<E> root, Set<TreeNode<E>> lcaSets){ | |
Map<TreeNode<E>, Integer> map = new LinkedHashMap<>(); | |
int count=0; | |
for(TreeNode<E> val:lcaSets){ | |
map.put(val,count); | |
count++; | |
} | |
BitSet booleanSets = new BitSet(count); | |
booleanSets.set(0,count,false); | |
TreeNode<E> lca = LCAMulti(root,booleanSets,map); | |
boolean finalResult = true; | |
for(int i=0;i<count;i++){ | |
finalResult = finalResult && booleanSets.get(i); | |
} | |
if(finalResult){ | |
return lca; | |
}else{ | |
return null; | |
} | |
} | |
private static <E> TreeNode<E> returnLCA(boolean flag, TreeNode<E> root, TreeNode<E> left, TreeNode<E> right){ | |
if(flag) | |
return root; | |
else if(left!=null && right!=null){ | |
return root; | |
} | |
else if(left!=null){ | |
return left; | |
}else if(right!=null){ | |
return right; | |
}else{ | |
return null; | |
} | |
} | |
private static <E> TreeNode<E> LCA(TreeNode<E> root, BitSet set, final TreeNode<E> first, final TreeNode<E> second){ | |
boolean flag = false; | |
if(root==null) | |
return null; | |
if(root.equals(first)){ | |
set.set(0,true); | |
flag=true; | |
} | |
if(root.equals(second)){ | |
set.set(1,true); | |
flag=true; | |
} | |
TreeNode<E> left = LCA(root.getLeft(), set,first, second); | |
TreeNode<E> right = LCA(root.getRight(), set, first, second); | |
return returnLCA(flag,root,left,right); | |
} | |
private static <E> TreeNode<E> LCAMulti(TreeNode<E> root, BitSet set, Map<TreeNode<E>, Integer> lcaMap){ | |
boolean flag = false; | |
if(root==null) | |
return null; | |
for(Map.Entry<TreeNode<E>, Integer> entry:lcaMap.entrySet()){ | |
TreeNode<E> node = entry.getKey(); | |
int bitPosition = entry.getValue(); | |
if(root.equals(node)){ | |
set.set(bitPosition,true); | |
flag=true; | |
} | |
} | |
TreeNode<E> left = LCAMulti(root.getLeft(), set,lcaMap); | |
TreeNode<E> right = LCAMulti(root.getRight(), set,lcaMap); | |
return returnLCA(flag,root,left,right); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment