in DS recategorized by
31,461 views
118 votes
118 votes
Suppose we have a balanced binary search tree $T$ holding $n$ numbers. We are given two numbers $L$ and $H$ and wish to sum up all the numbers in $T$ that lie between $L$ and $H$. Suppose there are $m$ such numbers in $T$. If the tightest upper bound on the time to compute the sum is $O(n^a\log^bn+m^c\log^dn)$, the value of $a+10b+100c+1000d$ is ______.
in DS recategorized by
31.5k views

4 Comments

During inorder traversal if we take elements between L and H then it take O(n) time(time for in order traversal) then why we do some extra work and pay extra cost O(log n). Because L and H is already given and L and H need not be in BST.

So answer is a=1 , b=0, c=0, d=0.

We can't take 'm' ='n' because in worst case all tree elements sum up.
0
0
edited by
3
3
edited by
Can it be done this way?

A hash table of size H can be initialized. // O(H) Space, let the table be Arr[H+1]
Next, all of the nodes till the target node can be marked visited in the table. O(logn) for 2 searches. (Remember, the nodes shall be only marked visited if were not visited before, to get rid of duplicate entries).
Finally, the hash table can be traversed, and the visited node’s sum can be calculated. // Start visiting from Arr[L]
Time Complexity : O(m+logn).
Auxiliary Space: O(H).
1
1

8 Answers

172 votes
172 votes
Best answer

In worst case for finding $L$ and $H$ it will take $O(\log n)$ time as the given tree is balanced binary search tree.
Now there are $m$ elements between $L$ and $H$. So to traverse m element it will take $O(m)$ time (traversal algorithm given below). So, total

$O(m+\log n)  \implies a=0, b=1,c=1,d=0$
$\therefore 0+(10 \times 1)+(100 \times 1)+(1000 \times 0)=110$. 


To find all the numbers from $L$ to $H$ we can do an inorder traversal from root and discard all elements before $L$ and after $H$. But this has $O(n)$ time complexity. So, we can do a modification to inorder traversal and combine with binary search as follows:

  1. Find $L$ using binary search and keep all nodes encountered in the search in a stack. 
  2. After finding $L$ add it to stack as well and initialize $\text{sum} = 0$.
  3. Now, for all nodes in stack, do an inorder traversal starting from their right node and adding the node value to sum. If $H$ is found, stop the algorithm. 
edited by

4 Comments

@shraddha_gami.

we are not doing it simultaneously . it is one after the other that’s why O(logn+m) and not O(mlogn).

0
0
bro i dont understand the difference between

those O(mlogn) and O(m +logn) for what u’ve said

for traversing to an element which is between L and H it takes logn time right?

then for m such elements it would be mlogn only right?

thats what i thought

if u see this please help me in making me understand my mistake brother

that would be helpful for my preparation for GATE this year 2024
0
0
# Please look into this.

def inorderTraversal(self, root, L, H):
        tot_sum = 0
        stack = []
        cur = root
        while stack or cur:
            if cur:
                stack.append(cur)
                cur=cur.left
            else:
                cur=stack.pop()
                if cur.val >= L and cur.val <= H:
                    tot_sum += cur.val
                cur=cur.right
        return tot_sum

 

What about my code. 

Its O(n) and the sum is directly calculated. In worst case m = n, so your algorithm O(m + logn) will be same as mine. Doesn't the ques ask about the worst case.

0
0
111 votes
111 votes

Here is an example 😊

$L =25 , H = 35$
Inorder: $10,15,20,\underset{L}{\boxed{25}},26,27,28,30,31,32,33,34,\underset{H}{\boxed{35}},36,39,42$

  1. Find $L$ and $H \rightarrow O(\log n)$ time.
  2. Traverse '$m$' elements between '$L$' and  '$H$' $\rightarrow O(m)$ [Traversal algorithm]

Total $\rightarrow  O(m + \log n) $

$\qquad a= 0,b=1,c=1,d=0$

$\qquad 10 + 100 = 110$ Answer

Traversal Algorithm:

  1. Find $L$ using Binary search and keep  $H>node> L$ encountered in the search in a stack.
  2. After finding $L,$ add it to stack as well & initialize $sum = 0$
  3.  Now, for all nodes in the stack, do an inorder traversal starting from their right node and adding the node value to sum. If it is found than stop the algorithm.
  • Node (1) 
    • No Right child; Sum = Sum + Node value $= 0 + 25 = 25.$
  • Node (2)
    • Inorder Traversal from Right Child $\rightarrow  24,28$
    • Sum = sum + inorder Traversal + Node Value $=  (25 + 27 + 28) + 26$
  • Node (3)
    • Inorder Traversal From Right Child $\rightarrow 31,32,33,34,\overset{H}{\bf{35}}\overset{\to \text{Stop Inorder Traversal}}{}$
    • Sum = Sum + Inorder Traversal + Node value
      • $\qquad = 25 + 26 + 24 + 28 + (31 + 32 + 33 + 34 + 35) + 30$
      • $\qquad = 25 + 26 + 24 + 28 + 30 + 31 + 32  + 33 + 34 + 35$  Answer

EDIT :

  1. In Step 1, we need to find only $L$ and not $H.$
  2. In Traversal Algo: Find $L$ using Binary Search and Keep, L< Nodes< H, encountered in the search in the stack.
edited by
by

20 Comments

Thanks for valuable effort.
1
1
@Chhotu

Now, I am having a doubt

Why traversal algo will take O(m) time ? :P
0
0

Why traversal algo will take O(m) time ? :P

OK, But first tell me why do you think we can access node > O(m) ?

0
0
I am thinking like this :

Maxi. in stack we could have logn nodes

for each of logn nodes we will do inorder traversal on right subtree.

tc=logn +m
1
1
Hi @VS ji,

Step (1) of your solution requires small correction( First we are only finding L)

Now for L we are doing in-order traversal of partially visited tree. In-order traversal gives output nodes in sorted order if it is BS-tree. So after traversal of m nodes. you will get your H also. I hope this helps.
1
1
VS is fine no need of "ji" or call me Vidhi

I got it :)

In first part we only need to Find L and no need of finding H.
1
1
@VS.Just a small addition, i think while pushing a node ,we should check if the node is <H.  Suppose in your tree i need sum from 15 to 23,then while going to left of 30, there is no need to push 30.In case we push ,then when we pop before adding we need to check that if the popped item from stack is <H.only then goto right subtree
11
11
thanx
1
1
Nice explanation ...
1
1
awesome explainantion !!!
0
0
nice explanation.. i wonder whether people were able to derive algo in exam
0
0
I just have one doubt wht we are using INORDER only??? why not any other traverasals....our main air to traverse from L to H right?? then why only INORDER ....
1
1
note, the given tree is a binary search tree(balanced) and only inorder traversal of bst guarentees elements in increasing order, we need to find elements sum between 2 elements let's say L and H. So we first find L and theen start inorder traversal after that so it guarenntes that all the elements between L and H will be found out that too in increasing order, and if you use any other traversal then there is a possibilty that you may add some extraa elements which are not b/w L and H(even if you come up with such an algorithm).
10
10
i think it should be best answer.. nice explanation.
0
0
can u provide me your notes pls if u have
0
0
I think the diagram needs and edit below node 25 there is node 26 which needs to be removed else inorder shoukd have two 26.Sorry if interpreted wrong.
2
2

A minor correction :

 

Node (2)

  • Inorder Traversal from Right Child →24,28

Instead of 24, it should be 27. 

2
2
Why only $25,26,30$ elements added into the stack?
0
0

 since its doing binary search to find L ..i.e. 25

so it will get to 30 first (mid) then left….of that since 25<30..so we will get 30,26,25…

 

But i have one doubt..

in this algorithm why we are assuming inorder traversal is given??

to find inorder traversal to get sorted numbers ..it will take O(n) right?

 

0
0
thanks.
0
0
25 votes
25 votes

int getSum(node *root, int L, int H)
{
   // Base Case
   if (root == NULL)
      return 0;

   if (root->key < L)        
       return getSum(root->right, L, H);

  if (root->key > H)
      return getSum(root->left, L, H)

   if (root->key >= L && root->key <=H)        
      return getSum(root->left, L, H) + root->key +
             getSum(root->right, L, H);
}

it will be O(logn +m)

it can go max of logn depth to find nodes in range and  function calls for nodes in range ie m

Note that the code first traverses across height to find the node which lies in range. Once such a node is found, it recurs for left and right children. Two recursive calls are made only if the node is in range. So for every node that is in range, we make at most one extra call (here extra call means calling for a node that is not in range).

source:http://geeksquiz.com/gate-gate-cs-2014-set-3-question-49/

3 Comments

Thanks for valuable effort.
1
1
So in worst case 'm' can equal to 'n', right?
1
1
# Please look into this.

def inorderTraversal(self, root, L, H):
        tot_sum = 0
        stack = []
        cur = root
        while stack or cur:
            if cur:
                stack.append(cur)
                cur=cur.left
            else:
                cur=stack.pop()
                if cur.val >= L and cur.val <= H:
                    tot_sum += cur.val
                cur=cur.right
        return tot_sum

 

What about my code. 

Its O(n) and the sum is directly calculated. In worst case m = n, so your algorithm O(m + logn) will be same as mine. Doesn't the ques ask about the worst case.

0
0
12 votes
12 votes
Do tree traversal from root as follows: Do a recursive search to find L, saving all the nodes visited in a stack. Since tree is balanced BST, it'll take O(log n) time. After finding L instead of search do inorder traversal up to m nodes from this node and continuing (if needed) using the saved nodes during searching. Complexity O(m).

Total time = O(m) + O(log n)

a=0, b=1, c=1, d=0
a+10b+100c+1000d = 0+ 10 + 100 + 0
= 110

4 Comments

sir, I have the same confusion. Have you got it now? Why is stack required here?

Just in case you read this, can this problem be solved by just finding L $[O(logn)\ time]$, then performing an inorder traversal for m+1 numbers $[O(m)\ time]$; then adding them up $[O(1)\ time]$

My point is, can it be solved simply like that, or am I missing something?

0
0

@JashanArora adding to your points, I think your approach is valid we just need to make sure that the values < L in inorder traversal must be dropped. Finally according to me we can solve it without using stack in the following way:

 

1. First find the value of L.

 

2. Now

IF  L has right node then initialise sum = L  ELSE sum = 0.

 

3. Now

IF  if L has right node do inoder traversal starting from the L's right node and keep on incrementing sum (making sure visited node values are >=  L if not then ignore those values ) with visited node value until we reach H. 

 

ELSE L itself is the right node so start inorder traversal from L itself and keep on incrementing sum ( again making sure visited node values are >=  L if not then ignore those values ) with visited node value until we reach H.

 

4. finally sum value is our answer.

 

@DigvijayPandey sir, @Arjun sir or anyone please correct me if I am wrong.

0
0
@Aadesh

This is wrong how can you do in-order traversal starting from L, as L will contribute a sub-tree of the whole. That’s why stack is needed to store the nodes that were visited before L.

And instead of ignoring values that are smaller than L , just do the in-order traversal of right-subtrees
0
0
Answer:

Related questions