Woodstock Blog

a tech blog for general algorithmic interview questions

[Facebook] Binary Search Tree 3Sum

Question

DLL - link

Inorder - link

Given a BST, write a function that returns true if there is a triplet that sums to 0, returns false otherwise.

Solution

We will solve the question just like we do [LeetCode 15] 3Sum. What is missing is an random access of tree nodes.

In fact, we do not need random access. Tree traversal (one after another in sequence) would be good enough.

Now there’re 2 solution. First is to convert the tree to Double-linked list, then do 3Sum. The conversion takes O(n) time and O(logn) extra space, and 3Sum take O(n2). however doing this modifies the original tree.

Second solution is to to inorder traversal and reversed inorder traversal. For me, this solution is preferred. Time and space used is same.

Code

DLL way, written by me

public void findTriplet(TreeNode root, int target) {
    TreeNode[] dll = convertToDll(root);
    TreeNode head = dll[0];
    TreeNode tail = dll[1];
    // note that the bst inorder dll should already in sorted by value
    TreeNode first = head;
    while (first.right != null) {
        TreeNode left = first.right;
        TreeNode right = tail;
        while (left.val < right.val) {
            int diff = first.val + left.val + right.val - target;
            if (diff == 0) {
                System.out.println("Found triplet: " + first.val + " "
                        + left.val + " " + right.val + " for sum of "
                        + target);
            }
            if (diff <= 0) {
                left = left.right;
            }
            if (diff >= 0) {
                right = right.left;
            }
        }
        first = first.right;
    }
}

private TreeNode[] convertToDll(TreeNode node) {
    TreeNode[] ans = new TreeNode[2];
    // do the left side of node
    if (node.left == null) {
        ans[0] = node;
    } else {
        TreeNode[] preAns = convertToDll(node.left);
        ans[0] = preAns[0];
        node.left = preAns[1];
        preAns[1].right = node;
    }
    // do the right side of node
    if (node.right == null) {
        ans[1] = node;
    } else {
        TreeNode[] postAns = convertToDll(node.right);
        ans[1] = postAns[1];
        node.right = postAns[0];
        postAns[0].left = node;
    }
    return ans;
}

inorder way - basically is just iterator of binary tree.