Originally posted by: ones3k
I'll post the solution to #1 so you believe me:
here it goes:
My solution is to create a binary tree with each leaf representing a stream. We construct the tree from the leaves up. Each node in the tree will contain an integer.
First we insert all K leaves and their corresponding integers (which will be the current element in each stream). From here we construct a "tournament" tree by pairing up nodes at each level and taking the smallest. At the root of the tree we will have the smallest item. Before we move on, please draw this incase im being confusing.
Next, notice that the smallest item (root), must of been compared against the second smallest.
So we increment the stream corresponding to our winning element and update our tree by pushing the new element through the same path as the old element. This is a log(k) operation and we are guaranteed to get the smallest every time because the smallest element beat the second smallest.
so its O(k) to set up the tree and access the first element and O(log(k)) for each stream access thereafter
Originally posted by: DrPizza
Originally posted by: ones3k
I'll post the solution to #1 so you believe me:
here it goes:
My solution is to create a binary tree with each leaf representing a stream. We construct the tree from the leaves up. Each node in the tree will contain an integer.
First we insert all K leaves and their corresponding integers (which will be the current element in each stream). From here we construct a "tournament" tree by pairing up nodes at each level and taking the smallest. At the root of the tree we will have the smallest item. Before we move on, please draw this incase im being confusing.
Next, notice that the smallest item (root), must of been compared against the second smallest.
So we increment the stream corresponding to our winning element and update our tree by pushing the new element through the same path as the old element. This is a log(k) operation and we are guaranteed to get the smallest every time because the smallest element beat the second smallest.
so its O(k) to set up the tree and access the first element and O(log(k)) for each stream access thereafter
That's what I've been waiting for since you originally posted this question over a week ago.
Originally posted by: brzrkr0
I guess they want people who are good at escaping from blenders.
On a more serious note, those questions definitely remind me of something I might see on a CS final exam. However, you'd probably have to be in a graduate-level course to see questions that difficult. A lot of those are beyond anything I had to deal with when working on my bachelor's.
How much time did you have to answer these?
sounds a lot more like a binary heap than a binary tree. with a binary heap, you're guaranteed a O(log K) access time since it's essentially a complete binary tree.. and since it's complete, you can allocate the heap as an array in contiguous memory (accesses to 2 different nodes won't be at different locations in memory).Originally posted by: ones3k
I'll post the solution to #1 so you believe me:
here it goes:
My solution is to create a binary tree with each leaf representing a stream. We construct the tree from the leaves up. Each node in the tree will contain an integer.
First we insert all K leaves and their corresponding integers (which will be the current element in each stream). From here we construct a "tournament" tree by pairing up nodes at each level and taking the smallest. At the root of the tree we will have the smallest item. Before we move on, please draw this incase im being confusing.
Next, notice that the smallest item (root), must of been compared against the second smallest.
So we increment the stream corresponding to our winning element and update our tree by pushing the new element through the same path as the old element. This is a log(k) operation and we are guaranteed to get the smallest every time because the smallest element beat the second smallest.
so its O(k) to set up the tree and access the first element and O(log(k)) for each stream access thereafter
if you insert all the values into a binary tree so that they're leaves and you take the smallest one as you go up, what're you gonna do if a sub-tree has 2 children (occurs after the 2nd level)? if it has 2 children, then whatever node is merged with it won't have anywhere to go. another problem comes up with keeping the tree sorted. if you insert them in the order you got them, if you only do merges with limited visibility you're running the risk that the tree has an odd order.. or if you do sort them before u insert them, then you'll produce a worst-case tree with a height of O(K).
also.. how would your algorithm handle the streams when log2(K) isn't an integer (results in a level without a pair)?
Originally posted by: itachi
err nm.. i was wrong about the sorted being O(K), but it still seems like it'd cause problems.
construct your tree with 1 2 3 4 5 as keys
if you 'push' each key down as you construct it without any reordering or reattaching (assuming you pair from left to right), the tree that results is
n 2 n 4 n n n n
n 3 n n
n 5
1
3 is seperated from 1 by 1 empty node.. 2 is seperated from 1 by 2 empty nodes.. 4 is a child of 3.
or let's say that if it has only 1 non-null child, it pulls that up.. if it has 2, it pulls up the smaller one.. construct the tree with 1 3 2 5 4
under the same scenario, you'll get
n n n n n n n n
3 5 n n
2 4
1
mm.. is that what u intended on?
yea.. that's the direction that i was trying to go in. his solution lacked an ordering property.Originally posted by: Matthias99
These sorts of scenarios are easily handled by something like a red-black tree (which prevents it from growing unbalanced at the cost of a little extra overhead, but maintains the same asymptotic complexity). It's a pretty basic data structures problem.
Originally posted by: itachi
err nm.. i was wrong about the sorted being O(K), but it still seems like it'd cause problems.
construct your tree with 1 2 3 4 5 as keys
if you 'push' each key down as you construct it without any reordering or reattaching (assuming you pair from left to right), the tree that results is
n 2 n 4 n n n n
n 3 n n
n 5
1
3 is seperated from 1 by 1 empty node.. 2 is seperated from 1 by 2 empty nodes.. 4 is a child of 3.
or let's say that if it has only 1 non-null child, it pulls that up.. if it has 2, it pulls up the smaller one.. construct the tree with 1 3 2 5 4
under the same scenario, you'll get
n n n n n n n n
3 5 n n
2 4
1
mm.. is that what u intended on?
the key is what you search/compare by. the values of the streams or a string in a tree of strings.Originally posted by: ones3k
I havre absolutely no idea about your notation. What do you mean by a "key" ?
yea, you should really specify that the tree is filled as it goes along. from what you said, i assumed you filled the tree before u started reading.What we do (and what i said in my initial post) is we select the winner of the tournament (which is the min out of all the streams, and this also the ROOT node) Now we go back to the leaf node corresponding to our winner and replace the value with the the next stream value. In other words, we INCREMENT the stream. Now we update the tourament tree by going along the path directly to the root. There is absolutely NO reason to use any type of balancing sscheme, and you have misunderstood my solution. I told you to draw this out, you'll realize whats going on.
The tree is STATIC
Originally posted by: ones3k
I'll post the solution to #1 so you believe me:
here it goes:
My solution is to create a binary tree with each leaf representing a stream. We construct the tree from the leaves up. Each node in the tree will contain an integer.
First we insert all K leaves and their corresponding integers (which will be the current element in each stream). From here we construct a "tournament" tree by pairing up nodes at each level and taking the smallest. At the root of the tree we will have the smallest item. Before we move on, please draw this incase im being confusing.
Next, notice that the smallest item (root), must of been compared against the second smallest.
So we increment the stream corresponding to our winning element and update our tree by pushing the new element through the same path as the old element. This is a log(k) operation and we are guaranteed to get the smallest every time because the smallest element beat the second smallest.
so its O(k) to set up the tree and access the first element and O(log(k)) for each stream access thereafter
Originally posted by: hypn0tik
I can do 5 and 6 and pretty sure can do 4. The others look pretty difficult.
Edit: Actually, I can't do 4. I underestimated the problem.