Quicksort algorithm - 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.

Related

Neighbors in the matrix - algorithm

I have a problem with coming up with an algorithm for the "graph" :(
Maybe one of you would be so kind and direct me somehow <3
The task is as follows:
We have a board of at least 3x3 (it doesn't have to be a square, it can be 4x5 for example). The user specifies a sequence of moves (as in Android lock pattern). The task is to check how many points he has given are adjacent to each other horizontally or vertically.
Here is an example:
Matrix:
1 2 3 4
5 6 7 8
9 10 11 12
The user entered the code: 10,6,7,3
The algorithm should return the number 3 because:
10 is a neighbor of 6
6 is a neighbor of 7
7 is a neighbor of 3
Eventually return 3
Second example:
Matrix:
1 2 3
4 5 6
7 8 9
The user entered the code: 7,8,6,3
The algorithm should return 2 because:
7 is a neighbor of 8
8 is not a neighbor of 6
6 is a neighbor of 3
Eventually return 2
Ofc number of operations equal length of array - 1
Sorry for "ile" and "tutaj", i'm polish
If all the codes are unique, use them as keys to a dictionary (with (row/col) pairs as values). Loop thru the 2nd item in user input to the end, check if math.Abs(cur.row-prev.row)+math.Abs(cur.col-prev.col)==1. This is not space efficient but deal with user input in linear complexity.
The idea is you have 4 conditions, one for each direction. Given any matrix of the shape n,m which is made of a sequence of integers AND given any element:
The element left or right will always be + or - 1 to the given element.
The element up or down will always be + or - m to the given element.
So, if abs(x-y) is 1 or m, then x and y are neighbors.
I demonstrate this in python.
def get_neighbors(seq,matrix):
#Conditions
check = lambda x,y,m: np.abs(x-y)==1 or np.abs(x-y)==m
#Pairs of sequences appended with m
params = zip(seq, seq[1:], [matrix.shape[1]]*(len(seq)-1))
neighbours = [check(*i) for i in params]
count = sum(neighbours)
return neighbours, count
seq = [7,8,6,3]
matrix = np.arange(1,10).reshape((3,3))
neighbours, count = get_neighbors(seq, matrix)
print('Matrix:')
print(matrix)
print('')
print('Sequence:', seq)
print('')
print('Count of neighbors:',count)
Matrix:
[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
Sequence: [10, 6, 7, 3]
Count of neighbors: 3
Another example -
seq = [7,8,6,3]
matrix = np.arange(1,10).reshape((3,3))
neighbours, count = get_neighbors(seq, matrix)
Matrix:
[[1 2 3]
[4 5 6]
[7 8 9]]
Sequence: [7, 8, 6, 3]
Count of neighbors: 2
So your input is the width of a table, the height of a table, and a list of numbers.
W = 4, H = 3, list = [10,6,7,3]
There are two steps:
Convert the list of numbers into a list of row/column coordinates (1 to [1,1], 5 to [2,1], 12 to [3,4]).
In the new list of coordinates, find consequent pairs, which have one coordinate identical, and the other one has a difference of 1.
Both steps are quite simple ("for" loops). Do you have problems with 1 or 2?

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.

Binary tree in concentric circles

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.

Binary Search in C++ with array

Here is an array with exactly 15 elements:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Suppose that we are doing a binary search for an element. Indicate any elements that will be found by examining two or fewer numbers from the array.
What I've got: as we are doing binary search, so the number found by only one comparison will be 7th element = 7. For two comparison, this leads to second division of array. That is, number found can be either 3 or 11.
Am I right or not?
You are almost right, the first number is not seven but eight.
The others 2 will then be 4 and 12.
The correct answer would be 4, 8, 12
`I found the answer to be 8 that is the 7th element, the other elements found were 3.5th and 10.5th element of the sorted array. So, the next two numbers delved are 4 and 11.
explanation on how i got the answers.
given array is 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
head=1
tail=15
middle= 0+14/2=7th element **0 is the index value of 1 and 14 is of 15**
middle value turns to be 8 as it is the 7th element.
solving value for first half
head=1
tail=8
middle= 0+7/2=3.5 or 3rd element **0 is the index value of 1 and 7 is of 8**
middle value now turns to be 4 as it is the 3rd element.
solving value for second half
head=8
tail=15
middle= 7+14/2=10.5 or 10th element **7 is the index value of 8 and 14 is
of 15**
middle value now turns to be 11 as it is the 10th element of the array`
Blockquote

Pair items from array in unique groups

I have an array of numbers ([1,2,3,4,5,6,7,8,9,10]). These numbers represent players. I would like these players to each "play" each other exactly once.
I need to create "Rounds" for these games. These rounds will include a even number of matches, and each player can only play in a round, at most, once. If there's an odd number of matches, than a final round with irregular number of matches is okay.
The end result being an array of "Round" arrays. These round arrays will contain the matches between players. The end result being something like below, but complete:
[[[1,2],[3,4],[5,6],[7,8],[9,10]],[[1,3],[2,4],[5,7],[6,8],[9,1],[10,2]]]
I've found Array#combination for getting the matches created, but I can't seem to get the rounds to build properly.
That is called a round robin tournament. Wikipedia gives the following algorithm
Round 1. (1 plays 14, 2 plays 13, ... )
1 2 3 4 5 6 7
14 13 12 11 10 9 8
then fix one competitor (number one in this example) and rotate the others clockwise one position:
Round 2. (1 plays 13, 14 plays 12, ... )
1 14 2 3 4 5 6
13 12 11 10 9 8 7
And keep rotating:
Round 3. (1 plays 12, 13 plays 11, ... )
1 13 14 2 3 4 5
12 11 10 9 8 7 6
An odd number of players is handled by one player per round having no game (often implemented by adding a dummy player).

Resources