2096. Step-By-Step Directions From a Binary Tree Node to Another
#binary-trees
Problem
Intuition
Explained in the code
Time Complexity
O(N) -> LCA
O(N) -> Traverse from LCA to start
O(N) -> Traverse from LCA to dest
Total time complexity = O(N) + O(N) + O(N) = 3 O(N) = O(N)
Space Complexity
O(h) -> LCA stack space
O(N) -> In worst case, there is a skewed tree and the path from left most node to right most
node is O(N)
Total Space complexity = O(h) + O(N) = O(N)
Solution
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public String getDirections(TreeNode root, int startValue, int destValue) {
// Time Complexity:
// O(N) -> LCA, O(N) -> Traverse from LCA to start, O(N) -> Traverse from LCA to des
// O(N) + O(N) + O(N) = 3 O(N) = O(N)
// Space Complexity:
// O(h) -> LCA stack space
// O(N) -> In worst case, there is a skewed tree and the path from left most node to right most
// node is O(N)
// O(h) + O(N) = O(N)
TreeNode lca = lcaHelper(root, startValue, destValue);
List<String> start = new ArrayList<>();
List<String> end = new ArrayList<>();
String s = "";
traverse(lca, start, startValue);
traverse(lca, end, destValue);
// Whatever the path is from LCA to startval, we explored it downwards using "L" and "R"
// But if we have to chart a path from start to LCA, then we only need to move "UP"
// So we replace the path with equivalent number of steps to UP
for(String dir: start) s += "U";
// Append the directions from LCA to destination value
for(String dir: end) s += dir;
return s;
}
private boolean traverse(TreeNode node, List<String> steps, int destVal) {
// If node is null, nothing more to traverse, we did not reach the destination
// So return false
if(node == null) return false;
// If we reach a node where its value is equal to destination value,
// then return true.
// The constraint of the question is all the nodes have unique values
if(node.val == destVal) return true;
// We perform traversal by checking out Left and Right
steps.add("L"); // Add "L" to the step for exploring Left side
// If we found the destination value by exploring left subtree, return true
if(traverse(node.left, steps, destVal)) return true;
// Once the left subtree is completely explored, then we return to the node
// So we remove the last "L" step
steps.remove(steps.size() - 1);
steps.add("R"); // Add "R" to the step for exploring Right side
// If we found the destination value by exploring right subtree, return true
if(traverse(node.right, steps, destVal)) return true;
// Once the right subtree is completely explored, then we return to the node
// So we remove the last "R" step
steps.remove(steps.size() - 1);
return false;
}
private TreeNode lcaHelper(TreeNode root, int start, int dest) {
// Standard LCA algorithm
if(root == null) return null;
if(root.val == start || root.val == dest) return root;
TreeNode left = lcaHelper(root.left, start, dest);
TreeNode right = lcaHelper(root.right, start, dest);
if(left == null) return right;
else if(right == null) return left;
else return root;
}
}
Last updated
Was this helpful?