Binary tree in concentric circles - algorithm

Recently I came across a question in an interview "Print a complete binary tree in concentric circles".
1
2 3
4 5 6 7
8 9 0 1 2 3 4 5
The output should be
1 2 4 8 9 0 1 2 3 4 5 7 3
5 6
Could anyone help me out on how we can solve this problem?

Here is how you can approach the problem. Arrange the tree by levels:
1
2, 3
4, 5, 6, 7
8, 9, 0, 1, 2, 3, 4, 5
So the data you have is k levels L1, L2, ..., Lk. Now answer this questions: After we execute one step, that is when one circle is traversed, how would the tree levels would look like after the traverse elements have been removed from the levels? How should I modify the levels and which elements should I print so that it would seems like I've traversed on circle?
In your example, after the first step the levels would be modified to just:
5, 6
So what was the operation that was executed?
After you've answered the questions just apply the same procedure couple of times until you've printed all elements.

Related

Confusion about a practical example of FIFO Page Replacement Algorithm?

I'm doing some theoretical examples with different page replacement algorithms, in order to get a better understanding for when I actually write the code. I'm kind of confused about this example.
Given below is a physical memory with 4 tiles (4 sections?). The following pages are visited one after the other:
R = 1, 2, 3, 2, 4, 5, 3, 6, 1, 4, 2, 3, 1, 4
Run the FIFO page replacement algorithm on R with 4 tiles.
I know that when a page needs to be swapped in, the operating system swaps out the page which has been in the memory for the longest period of time. In practice I'll have:
Time 1 2 3 4 5 6 7 8 9 10 11 12 13 14
Page 1 2 3 2 4 5 3 6 1 4 2 3 1 4
Tile 1 1 1 1 1 1 5 5
Tile 2 2 2 2 2 2 2
Tile 3 3 3 3 3 3
Tile 4 4 4 4
I'm not sure what happens at time = 8. I know that it won't replace page 5 and 4, but I'm not sure between 3 and 2. Since at time = 4 we have a 2, does it mean that page 3 will be replaced? Or is it that, since at time = 4, we already had 2 in the memory, therefore at time = 8 we replace 2?
FIFO (First In, First out) means here: If space is needed for a new entry, the oldest entry will be replaced. This is in contrast to LRU (Last recently Used), wherever the entry that has not been used for the longest time is replaced. Consider your memory with four tiles at time 5:
Tile Page Time of loading
1 1 1
2 2 2
3 3 3
4 4 5
At time 6, space for page 5 is needed, so you had to replace one of the pages in the memory. According to the FIFO principle, page 1 is replaced here:
Tile Page Time of loading
1 5 6
2 2 2
3 3 3
4 4 5
This event repeats itself at the time 8, the oldest page in memory will be replaced:
Tile Page Time of loading
1 5 6
2 6 8
3 3 3
4 4 5
So it is helpful here to write the time of creation while doing this assignment.

Euler18 dynamic algorithm

Given the array [5, 4, 12, 3, 11, 7, 2, 8, 1, 9] that forms a triangle like so:
5
4 12
3 11 7
2 8 1 9
Result should be 5 + 12 + 7 + 9 = 31.
Write a function that will traverse the triangle and find the largest possible sum of values when you can go from one point to either directly bottom left, or bottom right.
Refering to the dynamic algorithm in that link:
http://www.mathblog.dk/project-euler-18/
Result is 36.
5
4 12
3 11 7
2 8 1 9
5
4 12
11 19 16
5
23 31
36
Where is my mistake ??
The description of Problem 18 starts with an example where the optimal path is “left-right-right”. So you get a new choice of direction after every step, which means that after taking the first step to the right, you are still free to take the second step to the left and eventually come up with 5+12+11+8=36 as the optimal solution in your example, larger than the 31 you assumed. So the computation is correct in solving the problem as described. Your assumption about choosing a direction only once and then sticking with that choice would lead to a different (and rather boring) problem.

codejam 2015 qualification round: Infinite House of Pancakes

The problem description and solutions after contest analysis
There is one case I can't figure out: If there is one plate, 9 pancakes, that is the test case
1
9
the "correct answer" is 5
But how? Here is my "faulty" thinking:
9 -> {4, 5} -> {4,3,2} -> {3,2,2,2}
So it totals 3 + 3 = 6 minutes, not 5
Anything obvious that I misunderstood?
I managed to fail on this one during the competition too because I assumed that the best way was to split things in half (to get the maximum height reduction possible).
But, in viewing your question I can see a way that would do better then halving:
9 -> {6, 3} -> {3, 3, 3}
Two swaps plus three minutes to eat: 5 minutes
This has already been answered here:
Infinite House of Pancakes
Basically this is a case where dividing unevenly will give a better solution, for example:
9
3 6
3 3 3
2 2 2
1 1 1
0 0 0
Which is better than dividing evenly

Binary search tree -- ordering

If we have V values for a search tree where the values are V= {1,2,3,4,5,6,7} inserted from right to left
And we are to order it to get the largest and shortest height possible -- how would we do it? Would it require the best and worst (lg2 (n+1)) case??
And would the orderings be unique?
Thanks -- I kinda understand but am not sure on what steps i should take.
The largest height is easy; put them in order:
1
\
2
\
...
With the smallest height, sort them, take the middle as the root, and put the two sides one either branch. Rinse and repeat.
3
/ \
2 5
/ / \
1 4 6
\
7
So... n for the first one, and log_2(n) for the second (rounded up).
The tallest such trees are created by inserting the values from a sorted sequence
1 2 3 4 5 6 7
or
7 6 5 4 3 2 1
The shortest tree is made by ordering the values via a recursive algorithm that finds the median then processes the left and right subtrees recursively:
4 2 1 3 6 5 7
This produces a tree of logarithmic height:
4
/ \
2 6
/ \ / \
1 3 5 7
Here the median is 4, so that goes first.
4
Now you have a partition for the left (1, 2, 3) and right (5, 6, 7). To order the left, start with its median, 2. Now you have 1 and 3 for its subtrees. These are 1 element sets so that's your base case.
4 2 1 3
Now process your right subtree (5, 6, 7), starting with 6.
4 2 1 3 6 5 7

Quicksort algorithm

I used the quicksort algorithm to sort
11 8 9 4 2 5 3 12 6 10 7
and I got the list:
4 3 2 5 9 11 8 12 6 10 7.
5 was used as a pivot. Now I am stuck. How do I proceed to sort the lowersublist and the uppersublist?
pivot=5 11 8 9 4 2 5 3 12 6 10 7
Move pivot to position 0 5 8 9 4 2 11 3 12 6 10 7
i (position 1 = 8)
j (position 6 = 3) ⇒ swap 8 and 3 5 3 9 4 2 11 8 12 6 10 7
i (position 2 = 9)
j (position 4 = 2) ⇒ swap 9 and 2 5 3 2 4 9 11 8 12 6 10 7
i (position 3 = 4)
– no smaller elements than 5 ⇒ swap 5 and 4 4 3 2 5 9 11 8 12 6 10 7
– list after the partition
Quicksort is a recursive algorithm. Once you have sorted the elements by the pivot, you get two sets of items. The first with all elements smaller or equal to the pivot, and the second with all elements larger than the pivot. What you do now, is that you apply quicksort again to each of these sets (with an appropriate pivot).
To do this, you will have to choose a new pivot every time. You can do something like always pick the first element, or draw one at random.
Once you reach a point where a set contains only one element, you stop.
A good way to understand these things is to try to sort a deck of cards using this algorithm. All cards are face down, and you are only allowed to look at two cards at a time, compare these and switch them if necessary. You must pretend to not remember any of the cards that are face down for that to work.
A key component of the algorithm is that the chosen pivot value came from the original list, which means (in your case) the element with the value 5 is now in the correct final position after the first partitioning:
4 3 2 5 9 11 8 12 6 10 7
This should be fairly obvious and follows simple intuition. If every element to the left of an item is smaller than that item and every element to the right is larger, then the item must be in the correct, sorted position.
The insight necessary to understanding the entire Quicksort algorithm is that you can just keep doing this to each of the sublists -- the list of values to the left of the pivot and the list containing all values to the right -- to arrive at the final, sorted list. This is because:
Each partitioning puts one more element in its proper position
Each iteration removes one element -- the pivot -- from the list of elements left to process (which is why we'll eventually reach the base case of zero (or one, depending on how you do it) elements)
Let's assume you chose the partition value of 5 based on the following pseudo-code:
Math.floor(list.length / 2)
For our purposes, the actual choice of a pivot doesn't really matter. This one works for your orginal choice, so we'll go with it. Now, let's play this out 'till the end (starting where you left off):
concat(qs([4 3 2]), 5, qs([9 11 8 12 6 10 7])) =
concat(qs([2]), 3, qs([4]), 5, qs([9, 11, 8, 6, 10, 7]), 12, qs([])) =
concat(2, 3, 4, 5, qs([6, 7]), 8, qs([9, 11, 10]), 12) =
concat(2, 3, 4, 5, qs([6]), 7, qs([]), 8, qs([9, 10]), 11, qs([]), 12) =
concat(2, 3, 4, 5, 6, 7, 8, qs([9]), 10, qs([]), 11, 12) =
concat(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)
Note that each time you see a single call to qs it will follow this pattern:
qs(<some_left_list>), <the_pivot>, qs(<some_right_list>)
And each call of qs on one line results in two more such calls on the following line (representing the processing of both new sublists (except note that I immediately decompose calls to qs on single-value lists)).
It's a good idea to go through this exercise yourself. Yes, with actual pen and paper.

Resources