Skip to content

Commit

Permalink
Tree traversals
Browse files Browse the repository at this point in the history
  • Loading branch information
rusty-sj committed Sep 8, 2020
1 parent fe49f5d commit b26c9eb
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 0 deletions.
38 changes: 38 additions & 0 deletions ConstructTreeFromTraversalsI_LC105.java
@@ -0,0 +1,38 @@
/**
* We know for sure that first element from preorder traversal is the root node and thus use that to identify left
* and right part of tree from inorder array. Once we know the separation point, same length separation is followed by
* preorder traversal
* Form left and right inorder and preorder sub trees and iterate recursively util arrays are exhausted
*/
// Time Complexity: O (N) N: number of nodes in tree; Asymptotically
// Space Complexity: O (N) Space asymptotically and O(H) stack space for recursion where H is tree height
// Did this code successfully run on Leetcode : Yes
import java.util.Arrays;

public class ConstructTreeFromTraversalsI_LC105 {
public TreeNode buildTree(int[] preorder, int[] inorder) {
if (preorder == null || preorder.length == 0)
return null;

TreeNode root = new TreeNode(preorder[0]); // First index in preorder is root

int sepIndex = -1; // Find left right separation point as root is found
for (int i = 0; i < inorder.length; i++)
if (inorder[i] == root.val) {
sepIndex = i;
break;
}

int[] inLeft = Arrays.copyOfRange(inorder, 0, sepIndex);
int[] inRight = Arrays.copyOfRange(inorder, sepIndex + 1, inorder.length);

int[] preLeft = Arrays.copyOfRange(preorder, 1, sepIndex + 1);
int[] preRight = Arrays.copyOfRange(preorder, sepIndex + 1, preorder.length);

root.left = buildTree(preLeft, inLeft);
root.right = buildTree(preRight, inRight);

return root;

}
}
72 changes: 72 additions & 0 deletions SumRootToLeaf_LC129.java
@@ -0,0 +1,72 @@
// Time Complexity: O (N) N: number of nodes in tree
// Space Complexity: O(H) stack space for recursion where H is tree height
// Did this code successfully run on Leetcode : Yes

import java.util.Stack;

class StackNode {
TreeNode node;
int number;

StackNode(TreeNode node, int number) {
this.node = node;
this.number = number;
}
}

public class SumRootToLeaf_LC129 {
public int sumNumbers(TreeNode root) {
// return sumIterative(root);
return sumRecursive(root, 0);
}

/**
* Use inorder traversal to reach all possible leaf nodes. Use a stack that stores a node and number formed at that node.
* Traverse till leftmost node and then lookup stack to traverse right parts of node.
* Add to sum only when leaf nodes are reached.
*
* @param node
* @return
*/
int sumIterative(TreeNode node) {
if (node == null)
return 0;

int sum = 0, number = 0;
Stack<StackNode> stack = new Stack<>(); // Maintain stack

while (node != null || !stack.isEmpty()) { // Iterate until node is not null and stack isn't empty
while (node != null) {
number = number * 10 + node.val; // calculate number formed so far in tree path
stack.push(new StackNode(node, number));
node = node.left; // Keep going to left
}
StackNode popped = stack.pop();
node = popped.node;
number = popped.number;
if (node.left == null && node.right == null) // Add to sum only when leaf is reached
sum += number;
node = node.right; // Explore right
}
return sum;
}

/**
* Use terminating condition as when leaf is reached, return value formed at that leaf or when node is null
* return 0. Keep recursing left and right subtrees and add up the results from both
*
* @param node
* @param value
* @return
*/
int sumRecursive(TreeNode node, int value) {
if (node == null)
return 0;

value = value * 10;
value += node.val; // Calculate number formed from tree path
if (node.left == null && node.right == null)
return value; // leaf is reached, return value
return sumRecursive(node.left, value) + sumRecursive(node.right, value); // Recurse left and right subtree
}
}

0 comments on commit b26c9eb

Please sign in to comment.