diff --git a/java/step-by-step-directions-from-a-binary-tree-node-to-another.java b/java/step-by-step-directions-from-a-binary-tree-node-to-another.java new file mode 100644 index 0000000..57d6191 --- /dev/null +++ b/java/step-by-step-directions-from-a-binary-tree-node-to-another.java @@ -0,0 +1,70 @@ +class Solution { + private TreeNode getLowestCommonAncestor(TreeNode node, int key1, int key2) { + if (node == null) { + return null; + } + + if (node.val == key1 || node.val == key2) { + return node; + } + + var left = getLowestCommonAncestor(node.left, key1, key2); + var right = getLowestCommonAncestor(node.right, key1, key2); + + if (left == null) { + return right; + } + + if (right == null) { + return left; + } + + return node; + } + + private record Path(boolean found, StringBuilder path) {} + + private Path getPath(TreeNode node, int key, StringBuilder path) { + if (node == null) { + return new Path(false, path); + } + + if (node.val == key) { + return new Path(true, path); + } + + // go left + path.append('L'); + var leftPath = getPath(node.left, key, path); + if (leftPath.found) { + return leftPath; + } + path.deleteCharAt(path.length() - 1); + + // go right + path.append('R'); + var rightPath = getPath(node.right, key, path); + if (rightPath.found) { + return rightPath; + } + path.deleteCharAt(path.length() - 1); + + return new Path(false, path); + } + + public String getDirections(TreeNode root, int startValue, int destValue) { + var commonAncestor = getLowestCommonAncestor(root, startValue, destValue); + var pathToStart = getPath(commonAncestor, startValue, new StringBuilder()); + var pathToDest = getPath(commonAncestor, destValue, new StringBuilder()); + + var directions = new StringBuilder(); + + // gotta go up from the start + directions.repeat('U', pathToStart.path.length()); + + // and then follow the directions down + directions.append(pathToDest.path); + + return directions.toString(); + } +}