diff --git a/CrossTrainingI.java b/CrossTrainingI.java index bcf4947..75b8fbc 100644 --- a/CrossTrainingI.java +++ b/CrossTrainingI.java @@ -1,6 +1,7 @@ import java.util.*; import utils.TreeNode; import utils.TreeNodeP; +import utils.KnaryTreeNode; public class CrossTrainingI { public static void main(String[] args) { @@ -302,4 +303,88 @@ private void closestKValues(TreeNode node, PriorityQueue pq, int k, dou closestKValues(node.left, pq, k, target); closestKValues(node.right, pq, k, target); } + + /** + * Lowest Common Ancestor IV + *

+ * Given K nodes in a binary tree, find their lowest common ancestor. + */ + public TreeNode lowestCommonAncestor2(TreeNode root, List nodes) { + Set set = new HashSet<>(); + for (TreeNode n : nodes) { + set.add(n); + } + + return lowestCommonAncestor(root, set); + } + + private TreeNode lowestCommonAncestor(TreeNode node, Set set) { + if (node == null || set.contains(node)) { + return node; + } + + TreeNode left = lowestCommonAncestor(node.left, set); + TreeNode right = lowestCommonAncestor(node.right, set); + + if (left != null && right != null) { + return node; + } else { + return left == null ? right : left; + } + } + + /** + * Lowest Common Ancestor V + *

+ * Given two nodes in a K-nary tree, find their lowest common ancestor. + */ + public KnaryTreeNode lowestCommonAncestor3(KnaryTreeNode root, KnaryTreeNode a, KnaryTreeNode b) { + if (root == null || root == a || root == b) { + return root; + } + + KnaryTreeNode prev = null; + + for (KnaryTreeNode node : root.children) { + if (prev == null) { + prev = lowestCommonAncestor3(node, a, b); + } else { + if (lowestCommonAncestor3(node, a, b) != null) { + return root; + } + } + } + + return prev; + } + + /** + * Lowest Common Ancestor VI + *

+ * Given M nodes in a K-nary tree, find their lowest common ancestor. + */ + public KnaryTreeNode lowestCommonAncestor4(KnaryTreeNode root, List nodes) { + Set set = new HashSet<>(nodes); + return lowestCommonAncestor4(root, set); + } + + private KnaryTreeNode lowestCommonAncestor4(KnaryTreeNode root, Set set) { + if (root == null || set.contains(root)) { + return root; + } + + KnaryTreeNode prev = null; + + for (KnaryTreeNode node : root.children) { + if (prev == null) { + prev = lowestCommonAncestor4(node, set); + } else { + if (lowestCommonAncestor4(node, set) != null) { + return root; + } + } + } + + return prev; + } } diff --git a/utils/KnaryTreeNode.java b/utils/KnaryTreeNode.java new file mode 100644 index 0000000..ee2bc89 --- /dev/null +++ b/utils/KnaryTreeNode.java @@ -0,0 +1,13 @@ +package utils; + +import java.util.*; + +public class KnaryTreeNode { + public int key; + public List children; + + public KnaryTreeNode(int key) { + this.key = key; + this.children = new ArrayList<>(); + } +}