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.
Related
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
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.
In the work I'm doing, I declare an array with some length N.
At some point during my code, the data between certain elements needs to be removed.
If my initial array is [1,2,3,4,5], I want to change it to [1,2,4,5]. But I don't just do it once. The process will involved removing each element until there are no elements left and I may take out more than one element at once. The reason why I do this is related a complicated process I'm trying to reproduce and I don't think its necessary to go into this right now.
What I want to be able to do is define an array
a = (/ 1, 2, 3, 4, 5 /)
and if I decided to remove elements 3 and 4 I could set up a pointer (call it p) such that it would point to a as:
p = (/ 1, 2, 5 /)
Specifically, p will have length that is equal to a minus the number of elements removed. I'd want to do this morn than once. Redefine a
a = (/ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 /)
First I remove elements 4 and 5 and point to it such that
p = (/ 1, 2, 3, 6, 7, 8, 9, 10 /)
And then later removed 7,8,9 I could point to a
p = (/ 1, 2, 3, 6, 10 /)
Meanwhile keeping a intact. The p above would in my head be created by pointing to the first three elements of a and then the 6th and then the 10th all at once in one compact pointer.
I know I can probably achieve the same results with allocatable arrays, but I see pointers as being extremely useful.
No. An array pointer can be associated any array section, but not arbitrary elements.
Depending on what you later want to do, you can have a second array that lists the current indices in a, and then use vector subscripting for certain operations. But there are limitations for where a vector subscripted array can be used (e.g. if associated with a dummy argument it cannot be redefined), and in some cases the underlying implementation of a vector subscripted array may simply be to create a temporary contiguous copy of the relevant elements anyway.
I usually approach it using an allocatable (data) array, and also another logical array that is a mask for the data array. Then use the mask to keep track of what elements of the array are 'in use' or 'not in use'. When the need arises the active or 'in use' elements can be packed into either a final or intermediate array and if it is intermediate then the logical array reset to the size of the new data array.
And I generally avoid pointers.
PACK https://gcc.gnu.org/onlinedocs/gfortran/PACK.html and SUM(logical array) may be useful here.
It depends on whether the access speed to an arbitrary position in the array is more important than the speed of erasing elements.
If erasing elements is your priority, you should definitely make a linked list structure in which you are able to erase n elements at once.
If, on the other hand, what you need is access speed to the data you should use an array.
I need to design an algorithm that finds the k'th smallest element in unsorted array using function that called "MED3":
This function finds the n/3 (floor) and 2n/3 (ceil) elements of the array if it was sorted (very similar to median, but instead of n/2 it returns those values).
I thought about kind of partition around those 2 values, and than to continue like QuickSelect, but the problem is that "MED3" doesn't return indices of the 2 values, only the values.
for example, if the array is: 1, 2, 10, 1, 7, 6, 3, 4, 4 it returns 2 (n/3 value) and 4 (2n/3 value).
I also thought to run over the array and to take all the values between 2 and 4 (for example, in the given array above) to new array and then use "MED3" again, but can be duplicates (if the array is 2, 2, 2, 2, ..., 2 I would take all the elements each time).
Any ideas? I must use "MED3".
* MED3 is like a black box, it runs in linear time.
Thank you.
I think you're on the right track, but instead of taking 2 to 4, I'd suggest removing the first n/3 values that are <= MED3.floor() and the first n/3 values that are >= MED3.ceil(). That avoids issues with too many duplicates. If two passes/cycle aren't too expensive, you can remove all values < MED3.floor() + up to a total of n/3 values = MED3.floor() (do the same for ceil())
then repeat until you are at the k'th smallest target.
Need Hints to design an efficient algorithm that takes the following input and spits out the following output.
Input: two sorted arrays of integers A and B, each of length n
Output: One sorted array that consists of Cartesian product of arrays A and B.
For Example:
Input:
A is 1, 3, 5
B is 4, 8, 10
here n is 3.
Output:
4, 8, 10, 12, 20, 24, 30, 40, 50
Here are my attempts at solving this problem.
1) Given that output is n^2, Efficient algorithm can't do any better than O(n^2) time complexity.
2) First I tried a simple but inefficient approach. Generate Cartesian product of A and B. It can be done in O(n^2) time complexity. we need to store, so we can do sorting on it. Therefore O(n^2) space complexity too. Now we sort n^2 elements which can't be done better than O(n^2logn) without making any assumptions on the input.
Finally I have O(n^2logn) time and O(n^2) space complexity algorithm.
There must be a better algorithm because I've not made use of sorted nature of input arrays.
If there's a solution that's better than O(n² log n) it needs to do more than just exploit the fact that A and B are already sorted. See my answer to this question.
Srikanth wonders how this can be done in O(n) space (not counting the space for the output). This can be done by generating the lists lazily.
Suppose we have A = 6,7,8 and B = 3,4,5. First, multiply every element in A by the first element in B, and store these in a list:
6×3 = 18, 7×3 = 21, 8×3 = 24
Find the smallest element of this list (6×3), output it, replace it with that element in A times the next element in B:
7×3 = 21, 6×4 = 24, 8×3 = 24
Find the new smallest element of this list (7×3), output it, and replace:
6×4 = 24, 8×3 = 24, 7×4 = 28
And so on. We only need O(n) space for this intermediate list, and finding the smallest element at each stage takes O(log n) time if we keep the list in a heap.
If you multiply a value of A with all values of B, the result list is still sorted. In your example:
A is 1, 3, 5
B is 4, 8, 10
1*(4,8,10) = 4,8,10
3*(4,8,10) = 12,24,30
Now you can merge the two lists (exactly like in merge sort). You just look at both list heads and put the smaller one in the result list. so here you would select 4, then 8 then 10 etc.
result = 4,8,10,12,24,30
Now you do the same for result list and the next remaining list merging 4,8,10,12,24,30 with 5*(4,8,10) = 20,40,50.
As merging is most efficient if both lists have the same length, you can modify that schema by dividing A in two parts, do the merging recursively for both parts, and merge both results.
Note that you can save some time using a merge approach as is isn't required that A is sorted, just B needs to be sorted.