The Reversal Game - Scoring permutations using prefix reversals in order to generate only the highest scoring permutations - permutation

I am trying to create a "prefix reversal game" which generates only the permutations from n=2 (ie: {1,2}, {2,1}) to n=100, that require the highest number of prefix reversals in order to replace one at the beginning of the permutation.
For example,
{2, 4, 1, 3} (the first two elements reverse) -->
{4, 2, 1, 3} (the first four elements reverse) -->
{2, 1, 3, 4} (the first two elements reverse) -->
{1, 2, 3, 4} (end).
Therefore this permutation has a score of "4".
The part that I am having problems with is creating and implementing my own algorithm in order to find the highest scoring permutations without having to test every single one (because it is very inefficient). I was wondering if anybody could offer assistance in creating this algorithm.
I have been looking at algorithms such as the "pancake sorting" algorithm, but this seems to be the opposite of what I want.
Thank you so much for your time!

Related

Minimize number of insertions when sorting an array

Assuming an array where every element is also a positive integer number, without duplicates and without any missing elements, like the following:
{15, 1, 2, 6, 7, 8, 3, 4, 9, 5, 10, 13, 11, 12, 14}
Considering the removal and insertion (and not swaping) of each element, how can I find the most efficient move (remove/insert) operations to sort the list with the minimum number of insertions.
I think identifying individual groups is helpful since I can more easily find what needs to be moved together:
{{15}, {1, 2}, {6, 7, 8}, {3, 4}, {9}, {5}, {10}, {13}, {11, 12}, {14}}
For that I can create another array with the difference between the value and the correct position to let me easily identify the groups and which ones are furthest from being correct.
{{14}, {-1, -1}, {2, 2, 2}, {-4, -4}, {0}, {-5}, {-1}, {1}, {-2, -2}, {-1}}
Then I choosed the group furthest from being in the correct position (largest difference) and with smaller number of elements. So based on that I can see that {15} is 14 away from being correct and should be the first to be moved. I THINK (I'm guessing here) that I need to move AT least the difference in value, because I can land in the middle of group. Repeating the procedure I move the {5} to before {6,7,8}, which is moved 6 spaces, more difference between value and correct position because there is a group in its correct spot. Then {3,4}, and finally {13} and the list is sorted.
I can already create a iterative method that does just that. But I think it would be highly inefficient, since I will be dealing with about 200k values and recalculating it after every set of insertions is a terrible idea.
PS: I NEED to follow this procedure (remove and insertion of elements, and thinking in groups) instead of other more time efficient methods, since this would be applied in the real world to sort items in shelves, and something with a smaller number of operations of less items is prefered rather than computational or memory requirements.
Minimizing the number of elements that are moved is the same as maximizing the number of elements that are not moved.
Since any elements you don't move will be left in their original order, those elements must be a subsequence of the desired sorted array. You can use the common algorithm to find the longest such subsequence:
https://en.wikipedia.org/wiki/Longest_common_subsequence_problem
https://www.geeksforgeeks.org/longest-common-subsequence-dp-4/
Then remove all the elements that are not part of this subsequence, and reinsert them wherever they belong.
Note that there are optimizations you can use for this specific case of the longest monotonically increasing subsequence:
https://en.wikipedia.org/wiki/Longest_increasing_subsequence
https://www.geeksforgeeks.org/longest-increasing-subsequence-dp-3/
Create an integer array of size 16. Call it fred.
Init all of the values to 0
Iterate your unsorted array.
use each value as a subscript into fred, setting the value to 1.
Pretend your unsorted array is empty.
Iterate fred.
when you encounter a value of 1, that subscript needs to be inserted
back into your unsorted array.
Your unsorted array of size N is now sorted at a cost of N insertions

Searching for shortest slice in an array with all unique values, how to do this in optimal way?

I have an array that contains N elements, which values are in 0 <= value < N range and can be discontinuous. For this array I need to find a slice which will contain all unique values and at the same time it will be the shortest slice that will meet the above criterion.
An example, for array {1, 2, 1, 2, 1, 4, 3, 4, 8, 1, 8} with 5 unique values {1, 2, 3, 4, 8} we are talking about slice {2, 1, 4, 3, 4, 8} with length 6.
Is there an optimal way to do this? As for now I've naive implementation that has far too high complexity (nested loops). I've tried to come up with an idea for an algorithm to do this in an optimal way but sadly to no avail. As for now I've tried to come up with something that will make use of occurrences for each unique value when looping through array, but still my mind is not clear enough. Any ideas are welcome, this problem is troubling me for a long time. :) Thank you in advance.
Best regards
The first run collects possible values and creates a map with pairs (value; counter = 0). Let Nis map size
For the second run prepare two indexes - left and right, and ActiveCnt.
Move right, updating map counters. When you update zero counter, increment ActiveCnt. When ActiveCnt becomes equal to N, stop.
Now move left, decrementing map counters. When some counter becomes zero, get difference between right and left, compare it with current MinLength, then decrement ActiveCnt. Continue with right index and so on.

How do I calculate the k nearest numbers to the median?

I have an array of n pairwise different elements and a number k with 1<=k<=n.
Now I am looking for an algorithm calculating the k numbers with the minimal absolute difference to the median of the number array. I need linear complexity (O(n)).
My approach:
I find the median:
I sort the number
I get the middle element or if the number of elements id even then the average of the two elements in the middle and round.
After that:
I take every number and find the absolute distance from the median. These results I save in a different array
I sort the newly obtained array.
I take the first k elements of the result array and I'm done.
I don't know if my solution is in O(n), also whether I'm right with this idea. Can someone verify that? Can someone show me how to solve it in O(n)?
You can solve your problem like that:
You can find the median in O(n), w.g. using the O(n) nth_element algorithm.
You loop through all elements substutiting each with a pair: <the absolute difference to the median>, <element's value>. Once more you do nth_element with n = k. after applying this algorithm you are guaranteed to have the k smallest elements in absolute difference first in the new array. You take their indices and DONE!
Your algorithm, on the other hand uses sorting, and this makes it O(nlogn).
EDIT: The requested example:
Let the array be [14, 6, 7, 8, 10, 13, 21, 16, 23].
After the step for finding the median it will be reordered to, say: [8, 7, 9, 10, 13, 16, 23, 14, 21], notice that the array is not sorted, but still the median (13) is exactly in the middle.
Now let's do the pair substitution that got you confused: we create a new array of pairs: [<abs(14-13), 14>, <abs(6-13), 6>, <abs(7-13), 7>, <abs(8-13), 8>, <abs(10-13), 10>, <abs(13-13), 13>, <abs(21-13), 21>, <abs(16-13), 16>, <abs(23-13), 23>. Thus we obtain the array: [<1, 14>, <7, 6>, <6, 7>, <5, 8>, <3, 10>, <0, 13>, <8, 21>, <3, 16>, <10, 23>
If e.g. k is 4 we make once more nth_element(using the first element of each pair for comparisons) and obtain: [<1, 14>, <3, 16>, <0, 13>, <3, 10>, <8, 21>, <7, 6>, <10, 23>, <6, 7>, <5, 8>] so the numbers you search for are the second elements of the first 4 pairs: 14, 16, 13 and 10

Elements in array O(nlogn) complexity method for finding pairs

Okay, I keep getting stuck with the complexity here. There is an array of elements, say A[n]. Need to find all pairs so that A[i]>A[j] and also i < j.
So if it is {10, 8, 6, 7, 11}, the pairs would be (10,8) (10, 6), (10,7) and so on...
I did a merge sort in nlogn time and then a binary search for the entire array again in nlogn to get the indices of the elements in the sorted array.
So sortedArray={6 7 8 10 11} and index={3 2 0 1 4}
Irrespective of what I try, I keep getting another n^2 time in the complexity when I begin loops to compare. I mean, if I start for the first element i.e. 10, it is at index[2] which means there are 2 elements less than it. So if index[2]<index[i] then they can be accepted but that increases the complexity. Any thoughts? I don't want the code, just a hint in the right direction would be helpful.
Thanks. Everything i have been doing in C and time complexity is important here c
You cannot do this in under O(N^2), because the number of pairs that the algorithm will produce when the original array sorted in descending order is N(N-1)/2. You simply cannot produce O(N^2) results in O(N*LogN) time.
The result consists of O(n^2) elements, so any attempt to iterate through all pairs will be O(n^2).

Any ideas on How to search a 2D array quickly?

I jave a 2D array like this, just like a matrix:
{{1, 2, 4, 5, 3, 6},
{8, 3, 4, 4, 5, 2},
{8, 3, 4, 2, 6, 2},
//code skips... ...
}
(The Array is not sorted)
I want to get all the "4" position, instead of searching the array one by one, and return the position, how can I search it faster / more efficient? thz in advance.
You can't. There is no magic way. Your algorithm will always need to check each cell in your matrix, so it will always be O(n*m) for a matrix of size n * m.
If you can sort your matrix first, then you can get away with O(log(n) * m), as you can use a binary search inside each row.
The only way to do this is less than m * n is to have it presorted in some way. It is not clear from your question if that is possible.
There is no obvious algorithmic optimisation (unless you have some a priori knowledge of the data, e.g. that it's sorted, or you know how many 4s there are). However there are micro-optimisations that you can use, e.g. if your array is 32 bit int and you can use SSE then you can load and compare 4 elements at a time.
You can choose speed or memory consumption. If Memory is not important you could create a List of positions where values are stored. So you have still your m*n array, but additionaly an array of "position-lists". You would have to create "setter"-methods which write down a position in the lists each time a value is added or changed. So the idea is not to improve the search but avoid it.
Example:
You have a 2*2 Array.
{{0,0}
{0,0}}
And you want to add a 4 in the . So you have to call your method write which is called with the parameters X, Y, and Value. This method would change your array to
{{4,0},
{0,0}}
but also create a list
List4=>{(0,0)}
with the position of fours. If you add a second 4 it would look like
{{4,0}
{4,0}}
List4=>{(0,0),(1,0)}
So if you want to find all 4 in your matrix you just have to go to all positions in your List4. Of course you would have to create a list for each value in your array. So you could have a maximum of m*n lists with positions if the matrix contains each value only once.

Resources