↓ Skip to main content
Java

Building a tree from Traversal.

·2 mins

What good is an software engineer if he can’t keep revisiting the DS problems. It is like a pill for my laziness that keeps crawling ever so often.

The problem I am talking about is mentioned in this cool portal exercism.io that I use almost on a weekly basis.

The problem was to construct a tree from the inorder and preorder traversal.

In Order = LVR

Pre Order = VLR — Where L = Left, V = Vertex and R = Right

The complexity is basically recursively finding the root of the tree/subtree and the left and right subtree and managing the relations downwards or upwards.

Step 1: the first pre-order element is the root, and its position in the in-order list splits the left and right subtrees

The Logic is a multi step process

  1. Identify the root
    • The first element in the preorder traveral is always the root.
  2. Identify the left and the right subtree.
    • The elements from left to the index of root in the inorder are the left subtree
    • The elements from the right of the index of the root in the inorder are the right subtree.
  3. Identify the root of the subsequent subtree.

Let’s look at our example

    private Node buildNodes(List<Character> preOrder, List<Character> inOrder) {

        // If any of the tree is empty return null.
        if(preOrder.isEmpty() || inOrder.isEmpty()){
            return null;
        }

        // Root is always the first element in InOrder
        Node root = new Node(preOrder.get(0).charValue());
       

        // The Index of the root i identifies the Left and Right Subtree
        // 0 - i-1 is left and i+1 - n is the Right subtree
        int iRoot = inOrder.indexOf(preOrder.get(0));

        

        // Build the left tree first
        root.left = buildNodes(preOrder.subList(1, preOrder.size()), inOrder.subList(0, iRoot));

        // Build the right tree
        root.right = buildNodes(preOrder.subList(iRoot + 1, preOrder.size()), inOrder.subList(iRoot+1, inOrder.size()));

        return root;
    }

What do you think what more can I optimise?

Author
Samarthya
Engineer, learner, tinkerer. This is my trophy shelf of everyday work and leisure.

Related

Consumer

The utility package java.util.function has this functional interface Consumer. Each functional interface (Annotated with @FunctionalInterface) conceptually has a single method (abstract) called the functional method to which the lambda expression’s parameter and return types are matched against. Functional interfaces often represent abstract concepts like functions, actions, or predicates.

map and FlatMap

·2 mins
package java.util.stream; # Referring to the original Java 8 Documentation. <R> Stream<R> flatMap(Function<? super T,? extends Stream<? extends R>> mapper) Returns a stream consisting of Results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element. import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; public class Main { public static void main(String[] args) { // write your code here int myArray[] = { 1, 1, 2, 3, 4 , 5,6, 6,6, 7, 7, 7, 7, 7,7,3, 4, 3, 3, 2, 2, 2, 2, 2 }; // Simple map // Multiply each element by 5 Arrays.stream(myArray).map(index -> index * 5).forEach(System.out::println); } } The stream above multiplies each element by 5.

JavaStream: Characters

·1 min
Continuing from the last blog how about checking a pangram using streams. public class PangramChecker { private String allChars = "abcdefghijklmnopqrstuvwxyz"; public boolean isPangram(String input) { if (input.length() <= 0 || input.isBlank()){ return false; } return (allChars.chars().map(x -> (char) x).filter(x -> input.toLowerCase().indexOf(x) >= 0).count() == 26); } } All the for loops have been squeezed into a simple line