Search for items in BST that sum to a given value

I am trying to find an approach to solving the problem

Find two elements in balanced BST which sums to a given a value.

Limitations O (n) time and O (logn) space.

I was wondering if the following algorithm would be valid.

int[] findSum(Node root, int sum){
   int[] sumArray;
   for (int i=0;i<sum;i++) {
      if (root.contains(i) && root.contains(sum-i)) {
         sumArray[0] = i;
         sumArray[1] = sum-i;
      }
   }
}

I understand that my approach may be wrong. I would appreciate any feedback / corrections for my pseudo-codes / best algorithms

+5
source share
5 answers

I believe that the approach you have will work, but does not have the appropriate time limits.

. , . -, BST. BST , . n. -, , , . U.

, , . O (U) , BST. BST O (log n), - O (U log n). ( O (1)).

, . (, 1,000,000,000), , U .

, , . , , , , BST .

, , . , BST , : , ? , :

 0  1  3  6  8  9  10  14  19

, , 16. ?

, : , 0 16, 1 15, 2 14 .. , . O (log n) , O (U log n). (, , , , O (U log log n) , U- - ).

, . , , , , , U. , , , , , :

  • x , U-x .
  • , .
  • , , .

, O (n) , , O (log n) , . O (n log n) O (1) . , , U - , U!

, . , x U - x. , . , , , U - x. z.

, , , y , U, , , y , x. ,

y + z

> x + z

> x + (U - x)

= U

, y z U, U. ? , z, , x, U. , z , , x, U. , z - , x. , z, - , x, - , U.

, . , , , , 16:

 0  1  3  6  8  9  10  14  19

- " " lhs " " rhs:

 0  1  3  6  8  9  10  14  19
 ^                          ^
lhs                        rhs

, 19, U. , , , , , lhs, 0. , , 19, , . , 19.

 0  1  3  6  8  9  10  14  19
 ^                      ^
lhs                    rhs

(14), . , , , , 0, , 16, 14. , 0:

 0  1  3  6  8  9  10  14  19
    ^                   ^
   lhs                 rhs

:

  • , lhs.
  • , .

, , 16, lhs rhs , , 16.

,

 0  1  3  6  8  9  10  14  19
    ^                   ^
   lhs                 rhs    (sum is 15, too small)

 0  1  3  6  8  9  10  14  19
       ^                ^
      lhs              rhs    (sum is 17, too big)

 0  1  3  6  8  9  10  14  19
       ^            ^
      lhs          rhs        (sum is 13, too small)

 0  1  3  6  8  9  10  14  19
          ^         ^
         lhs       rhs        (sum is 16, we're done!)

! .

, ? , , lhs , rhs , , . , O (n) . , O (1). O (n).

? , , O (1), - O (1). !

? : . . , .

, . , node . , , , "increment lhs" "decment rhs" " lhs" " rhs." , O (log n) ( , ) , n O (n) ( , ). , BST, , O (n) O (log n) space!

, . , , , . BST . , .

, !

+7

, . -, sum, ? ? , .

node, , node, node, .

.

, , 17. 0, , , 17 -0. , 0 1 17-1, , 17.

Edit

//we're looking for two numbers that equal 17 when added
Node runner;
Node root;
int i;
int [] sum_total;

void findSum(int sum){
    int search_1st = 0;
    sum_total = new int[2];
    search(int search_1st);
}   

search( Node root, int num1){
    if(i == 3){
        return;
    }
    Node runner = root;
    if(ruunner == null){
    return ;
    }
    if(runner.element == num1){
        sum_total[i] = num1;
        i++;
        if(i == 3){
            return;
        }
        //now search for sum - num1 with root
        search(root, sum - num1);
    }else{
        if(runner.left < num1){
            search(runner.right, num1);
        }else{
            search(runner.left, num1);
        }
    }
}
0

http://www.geeksforgeeks.org/find-a-pair-with-given-sum-in-bst/

/* In a balanced binary search tree isPairPresent two element which sums to
   a given value time O(n) space O(logn) */
#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 100

// A BST node
struct node
{
    int val;
    struct node *left, *right;
};

// Stack type
struct Stack
{
    int size;
    int top;
    struct node* *array;
};

// A utility function to create a stack of given size
struct Stack* createStack(int size)
{
    struct Stack* stack =
        (struct Stack*) malloc(sizeof(struct Stack));
    stack->size = size;
    stack->top = -1;
    stack->array =
        (struct node**) malloc(stack->size * sizeof(struct node*));
    return stack;
}

// BASIC OPERATIONS OF STACK
int isFull(struct Stack* stack)
{   return stack->top - 1 == stack->size;  }

int isEmpty(struct Stack* stack)
{   return stack->top == -1;   }

void push(struct Stack* stack, struct node* node)
{
    if (isFull(stack))
        return;
    stack->array[++stack->top] = node;
}

struct node* pop(struct Stack* stack)
{
    if (isEmpty(stack))
        return NULL;
    return stack->array[stack->top--];
}

// Returns true if a pair with target sum exists in BST, otherwise false
bool isPairPresent(struct node *root, int target)
{
    // Create two stacks. s1 is used for normal inorder traversal
    // and s2 is used for reverse inorder traversal
    struct Stack* s1 = createStack(MAX_SIZE);
    struct Stack* s2 = createStack(MAX_SIZE);

    // Note the sizes of stacks is MAX_SIZE, we can find the tree size and
    // fix stack size as O(Logn) for balanced trees like AVL and Red Black
    // tree. We have used MAX_SIZE to keep the code simple

    // done1, val1 and curr1 are used for normal inorder traversal using s1
    // done2, val2 and curr2 are used for reverse inorder traversal using s2
    bool done1 = false, done2 = false;
    int val1 = 0, val2 = 0;
    struct node *curr1 = root, *curr2 = root;

    // The loop will break when we either find a pair or one of the two
    // traversals is complete
    while (1)
    {
        // Find next node in normal Inorder traversal. See following post
        // http://www.geeksforgeeks.org/inorder-tree-traversal-without-recursion/
        while (done1 == false)
        {
            if (curr1 != NULL)
            {
                push(s1, curr1);
                curr1 = curr1->left;
            }
            else
            {
                if (isEmpty(s1))
                    done1 = 1;
                else
                {
                    curr1 = pop(s1);
                    val1 = curr1->val;
                    curr1 = curr1->right;
                    done1 = 1;
                }
            }
        }

        // Find next node in REVERSE Inorder traversal. The only
        // difference between above and below loop is, in below loop
        // right subtree is traversed before left subtree
        while (done2 == false)
        {
            if (curr2 != NULL)
            {
                push(s2, curr2);
                curr2 = curr2->right;
            }
            else
            {
                if (isEmpty(s2))
                    done2 = 1;
                else
                {
                    curr2 = pop(s2);
                    val2 = curr2->val;
                    curr2 = curr2->left;
                    done2 = 1;
                }
            }
        }

        // If we find a pair, then print the pair and return. The first
        // condition makes sure that two same values are not added
        if ((val1 != val2) && (val1 + val2) == target)
        {
            printf("\n Pair Found: %d + %d = %d\n", val1, val2, target);
            return true;
        }

        // If sum of current values is smaller, then move to next node in
        // normal inorder traversal
        else if ((val1 + val2) < target)
            done1 = false;

        // If sum of current values is greater, then move to next node in
        // reverse inorder traversal
        else if ((val1 + val2) > target)
            done2 = false;

        // If any of the inorder traversals is over, then there is no pair
        // so return false
        if (val1 >= val2)
            return false;
    }
}

// A utility function to create BST node
struct node * NewNode(int val)
{
    struct node *tmp = (struct node *)malloc(sizeof(struct node));
    tmp->val = val;
    tmp->right = tmp->left =NULL;
    return tmp;
}

// Driver program to test above functions
int main()
{
    /*
                   15
                /     \
              10      20
             / \     /  \
            8  12   16  25    */
    struct node *root =  NewNode(15);
    root->left = NewNode(10);
    root->right = NewNode(20);
    root->left->left = NewNode(8);
    root->left->right = NewNode(12);
    root->right->left = NewNode(16);
    root->right->right = NewNode(25);

    int target = 28;
    if (isPairPresent(root, target) == false)
        printf("\n No such values are found\n");

    getchar();
    return 0;
}
0

, HashSet. , , (target - nodeValue) . O (n) , O (n).

0

The idea is the same as in the earlier solution, I just do it with two stacks - one after inorder (stack1) and the other the next order in reverse order (stack2). Once we reach the leftmost and rightmost node in BST, we can begin to compare them.

If the sum is less than the required value, pop out of stack1, otherwise pop from stack2. The following is a Java implementation:

public int sum2(TreeNode A, int B) {
    Stack<TreeNode> stack1 = new Stack<>();
    Stack<TreeNode> stack2 = new Stack<>();
    TreeNode cur1 = A;
    TreeNode cur2 = A;

    while (!stack1.isEmpty() || !stack2.isEmpty() ||
            cur1 != null || cur2 != null) {
        if (cur1 != null || cur2 != null) {
            if (cur1 != null) {
                stack1.push(cur1);
                cur1 = cur1.left;
            }

            if (cur2 != null) {
                stack2.push(cur2);
                cur2 = cur2.right;
            }
        } else {
            int val1 = stack1.peek().val;
            int val2 = stack2.peek().val;

            // need to break out of here
            if (stack1.peek() == stack2.peek()) break;

            if (val1 +  val2 == B) return 1;

            if (val1 + val2 < B) {
                cur1 = stack1.pop();
                cur1 = cur1.right;
            } else {
                cur2 = stack2.pop();
                cur2 = cur2.left;
            }
        }
    }

    return 0;
}
0
source

All Articles