Binary Tree Transformation - How to Succeed in Algorithms Interview


Binary Tree Transformation - How to Succeed in Algorithms Interview

How to Succeed in Algorithms Interview Series


Implementation of Bianry Tree Transformation

  • return new root
  • update left/right pointer while traverse
    • root.left/right = convert(root.left, ..);
  • or track prev

Example

public TreeNode trimBST(TreeNode root, int L, int R) {
  if (root == null)
    return root;
  if (root.val > R)
    return trimBST(root.left, L, R);
  if (root.val < L)
    return trimBST(root.right, L, R);
  root.left = trimBST(root.left, L, R);
  root.right = trimBST(root.right, L, R);
  return root;
}
static Node pruneUtil(Node root, int k,  
                      INT sum)  
{  
    if (root == null) return null;  
    INT lsum = new INT(sum.v + (root.data));  
    INT rsum = new INT(lsum.v);  
    root.left = pruneUtil(root.left, k, lsum);  
    root.right = pruneUtil(root.right, k, rsum);  
    sum.v = max(lsum.v, rsum.v);  
    if (sum.v < k)  
    {  
        root = null;  
    }  
    return root;  
}  

public Node prune(Node root, int sum) {
    if (root == null)
        return null;
    root.left = prune(root.left, sum - root.data);
    root.right = prune(root.right, sum - root.data);
    // if node is a leaf node whose data is smaller
    // than the sum we delete the leaf.An important
    // thing to note is a non-leaf node can become
    // leaf when its children are deleted.
    if (isLeaf(root)) {
        if (sum > root.data)
            root = null;
    }
    return root;
}  
public TreeNode upsideDownBinaryTree(TreeNode root) {
  if (root == null) {
    return null;
  }
  return upsideDownBinaryTree(root, null);
}

private TreeNode upsideDownBinaryTree(TreeNode root, TreeNode parent) {
  if (root == null) {
    return parent;
  }
  TreeNode newNode = upsideDownBinaryTree(root.left, root);
  root.left = parent == null ? null : parent.right;
  root.right = parent;
  return newNode;
}

public TreeNode upsideDownBinaryTree(TreeNode root) {
  if (root == null || root.left == null)
    return root;
  TreeNode newRoot = upsideDownBinaryTree(root.left);
  // root.left is newRoot everytime
  root.left.left = root.right;
  root.left.right = root;
  root.left = null;
  root.right = null;
  return newRoot;
}

public TreeNode upsideDownBinaryTree(TreeNode root) {
  TreeNode p = root, parent = null, parentRight = null;
  while (p != null) {
    TreeNode left = p.left;
    TreeNode right = p.right;
    p.left = parentRight;
    p.right = parent;
    parent = p;
    parentRight = right;
    p = left;
  }
  return parent;
}

BST example

  • LeetCode 538 - Convert BST to Greater Tree
    • reverse inorder traversal
    TreeNode prev;
    public TreeNode convertBST(TreeNode root) {
    if (root == null)
      return null;
    convertBST(root.right);
    root.val += prev == null ? 0 : prev.val;
    prev = root;
    convertBST(root.left);
    return root;
    }
  • LeetCode 108 - Convert Sorted Array to Binary Search Tree
  • LeetCode 109 - Convert Sorted List to Balanced Binary Search Tree (BST)
    private TreeNode convertListToBST(int l, int r) {
    // Invalid case
    if (l > r) {
      return null;
    }
    int mid = (l + r) / 2;
    // First step of simulated inorder traversal. Recursively form
    // the left half
    TreeNode left = this.convertListToBST(l, mid - 1);
    // Once left half is traversed, process the current node
    TreeNode node = new TreeNode(this.head.val);
    node.left = left;
    // Maintain the invariance mentioned in the algorithm
    this.head = this.head.next;
    // Recurse on the right hand side and form BST out of them
    node.right = this.convertListToBST(mid + 1, r);
    return node;
    }
    private ListNode node;
    inorderHelper(0, size - 1);
    public TreeNode inorderHelper(int start, int end){
      if(start > end){
          return null;
      }
      int mid = start + (end - start) / 2;
      TreeNode left = inorderHelper(start, mid - 1);
      TreeNode treenode = new TreeNode(node.val);
      treenode.left = left;
      node = node.next;
      TreeNode right = inorderHelper(mid + 1, end);
      treenode.right = right;
      return treenode;
    }
  • LeetCode 450 - remove node from binary search tree
    public TreeNode deleteNode(TreeNode root, int key) {
      if(root == null){
          return null;
      }
      if(key < root.val){
          root.left = deleteNode(root.left, key);
      }else if(key > root.val){
          root.right = deleteNode(root.right, key);
      }else{
          if(root.left == null){
              return root.right;
          }else if(root.right == null){
              return root.left;
          }
    
          TreeNode minNode = findMin(root.right);
          root.val = minNode.val;
          root.right = deleteNode(root.right, root.val);
      }
      return root;
    }
  • LeetCode 776 - Split BST
public TreeNode[] splitBST(TreeNode root, int V) {
    if (root == null)
        return new TreeNode[]{null, null};
    if (root.val == V) {
        TreeNode right = root.right;
        root.right = null;
        return new TreeNode[]{root, right};
    }
    else if (root.val > V) {
        TreeNode[] nodes = splitBST(root.left, V);
        TreeNode left = nodes[0];
        TreeNode right = nodes[1];
        root.left = right;
        return new TreeNode[]{left,root};
    } else {
        TreeNode[] nodes = splitBST(root.right, V);
        TreeNode left = nodes[0];
        TreeNode right = nodes[1];
        root.right=left;
        return new TreeNode[]{root, right};
    }
}
  • HARD Construct a Binary Search Tree from given postorder
    public TreeNode deserializeArrayOptimized(int[] postorder, int[] currIndex, int min, int max)
    {
    if (currIndex[0] < 0) return null;
    TreeNode root = null;
    if ((postorder[currIndex[0]] > min) && (postorder[currIndex[0]] < max))
    {
        root = new TreeNode(postorder[currIndex[0]]);
        currIndex[0] -= 1;
        root.right = deserializeArrayOptimized(postorder, currIndex, root.val, max);
        root.left = deserializeArrayOptimized(postorder, currIndex, min, root.val);
    }     
    return root;
    }
    Node constructTreeUtil(int post[], int n)
    {
      Node root = new Node(post[n - 1]);
      Stack<Node> s = new Stack<>();
      s.push(root);
      for (int i = n - 2; i >= 0; --i) {
          Node x = new Node(post[i]);
          Node temp = null;
          while (!s.isEmpty() && post[i] < s.peek().data)  
              temp = s.pop();       
          // Make x as left child of temp    
          if (temp != null)  
              temp.left = x;       
          // Else make x as right of top       
          else
              s.peek().right = x;
          s.push(x);
      }
      return root;
    }
  • Construct Binary Search Tree from a given Preorder
    public int pIndex = 0;
    public Node constructTree(int[] preorder, int data, int min, int max) {
    if (pIndex < preorder.length) {
      if (preorder[pIndex] > min && preorder[pIndex] < max) {
        Node root = new Node(data);
        pIndex++;
        if (pIndex < preorder.length) {
          root.left = constructTree(preorder, preorder[pIndex], min,data);
          root.right = constructTree(preorder, preorder[pIndex],data, max);
        }
        return root;
      }
    }
    return null;
    }
    public Node constructTree(int[] preorder) {
    Stack<Node> s = new Stack<Node>();
    Node root = new Node(preorder[0]);
    s.add(root);
    for (int i = 1; i < preorder.length; i++) {
      Node x = null;
      while (!s.isEmpty() && preorder[i] > s.peek().data) {
        x = s.pop();
      }
      if (x != null) {
        x.right = new Node(preorder[i]);
        s.push(x.right);
      } else {
        s.peek().left = new Node(preorder[i]);
        s.push(s.peek().left);
      }
    }
    return root;
    }

Tree Creation/Conversion

Tree - Creation

Map<Integer, Integer> postMap = new HashMap<>();
public TreeNode constructFromPrePost(int[] pre, int[] post) {
    int length = pre.length;
    for(int i = 0; i < post.length; i++) {
        postMap.put(post[i], i);
    }
    return build(0, length - 1, 0, length - 1, pre, post);
}
private TreeNode build(int preLeft, int preRight, int postLeft, int postRight, int[] pre, int[] post) {
    if(preLeft > preRight || postLeft > postRight) {
        return null;
    }
    TreeNode root = new TreeNode(pre[preLeft]);
    if(preLeft + 1 <= preRight) {
        int index = postMap.get(pre[preLeft + 1]);
        int sum = index - postLeft;
        root.left = build(preLeft + 1, preLeft + sum + 1, postLeft, index, pre, post);
        root.right = build(preLeft + sum + 2, preRight, index + 1, postRight - 1, pre, post);
    }
    return root;
}

public TreeNode constructFromPrePost(int[] pre, int[] post) {
  Stack<TreeNode> stack = new Stack<>();
  TreeNode root = new TreeNode(pre[0]);
  stack.push(root);
  for (int i = 1, j = 0; i < pre.length; ++i) {
    TreeNode node = new TreeNode(pre[i]);
    while (stack.peek().val == post[j]) {
      stack.pop();
      j++;
    }
    if (stack.peek().left == null) {
      stack.peek().left = node;
    } else {
      stack.peek().right = node;
    }
    stack.push(node);
  }
  return root;
}

Serialization

Labels

adsense (5) Algorithm (69) Algorithm Series (35) Android (7) ANT (6) bat (8) Big Data (7) Blogger (14) Bugs (6) Cache (5) Chrome (19) Code Example (29) Code Quality (7) Coding Skills (5) Database (7) Debug (16) Design (5) Dev Tips (63) Eclipse (32) Git (5) Google (33) Guava (7) How to (9) Http Client (8) IDE (7) Interview (88) J2EE (13) J2SE (49) Java (186) JavaScript (27) JSON (7) Learning code (9) Lesson Learned (6) Linux (26) Lucene-Solr (112) Mac (10) Maven (8) Network (9) Nutch2 (18) Performance (9) PowerShell (11) Problem Solving (11) Programmer Skills (6) regex (5) Scala (6) Security (9) Soft Skills (38) Spring (22) System Design (11) Testing (7) Text Mining (14) Tips (17) Tools (24) Troubleshooting (29) UIMA (9) Web Development (19) Windows (21) xml (5)