I have an unsorted array of size n and I need to find k-1 divisors so every subset is of the same size (like after the array is sorted).
I have seen this question with k-1=3. I guess I need the median of medians and this is will take o(n). But I think we should do it k times so o(nk).
I would like to understand why it would take o(n logk).
For example: I have an unsorted array with integers and I want find the k'th divisors which is the k-1 integers that split the array into k (same sized) subarrays according to their values.
If I have [1, 13, 6, 7, 81, 9, 10, 11] the 3=k dividers is [7 ,11] spliting to [1 6, 9 10 13 81] where every subset is big as 2 and equal.
You can use a divide-and-conquer approach. First, find the (k-1)/2th divider using the median-of-medians algorithm. Next, use the selected element to partition the list into two sub-lists. Repeat the algorithm on each sub-list to find the remaining dividers.
The maximum recursion depth is O(log k) and the total cost across all sub-lists at each level is O(n), so this is an O(n log k) algorithm.
Related
You have an array of integers. you have to find the number of subarrays which mean (sum of those elements divided by the count of those elements) rounds to zero.
I have solved this with O(n^2) time but it is not efficient enough. Is there a way to do it?
example:
[-1, 1, 5, 4]
subarrays which mean rounds to zero are:
[-1, 1] = 0 , [-1, 1, 5, -4] = 1/4 which rounds to zero
Denote new array composed of pairs (prefix sum, cnt) where first element is the prefix summation and second element is number of elements, for example,
int[] arr = [-1, 1, 5 ,4]:
int[] narr = [(0, 0), (-1, 1), (0, 2), (5, 3), (9, 4)]
the question is converted to count pair (i, j) in narr where i < j and Math.abs(narr[j][0] - narr[i][0]) < narr[j][1] - narr[i][1] = j - i which is further boiled down to:
narr[j][0] - j < narr[i][0] - i < narr[i][0] + i < narr[j][0] + j
so the question is further converted to the following question:
for some intervals: [[1, 2], [-1, 0], ...] (initially is empty), given an interval [x, y], count how many intervals are totally within the range of [x, y], then we add this interval, and repeat this procedure for total N times. (how to manage the data structure of intervals become the key problem)
If we just brute force iterate every intervals and do the validation, the query time complexity is O(N) and insertion time complexity is O(1), total O(N^2)
If we use square decomposition, the query time complexity is O(sqrt(N)) and insertion time complexity is O(1) , total O(Nsqrt(N))
If we use treap (using first or second as priority, use another as key), the average total time complexity we can achieve is O(NlgN)
If you don't know the technique of square decomposition or treap , I suggest you reading couple of articles first.
Update:
After carefully 30 mins thinking, I find treap cannot achieve O(NlgN) average time complexity.
Instead we can use 2d segment tree to achieve O(NlgNlgN):
Please read this article instead:
2d segment tree
I have a sequential odd array starting at 3. So x = {3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13...}.
I am wondering if there is a quick way to find at what index the square of a number n is at. So if n was 5, I am looking for where 25 is in the array. Right now I have ((n) * (n - 1)) which I add to the current i index. Is there anything faster?
Your array is made of consecutive numbers and it's sorted, Because of this it forms a mathematical arithmetic progression with difference 1 and first element as 3, so at index i we have a[i]=i+3 and so i=a[i]-3.
So to find the index of the square of n let nsqr be n*n, nsqr index is simply nsqr-3, that's an O(1) algorithm.
To make it general whenever we have consecutive sorted numbers which start with a0 and differ by d, to find where is the square of n we do (nsqr-a0)/d.
Given an array A of size N, we construct a list containing all possible subarrays of A in descending order.
Two subarrays B and C are compare by padding zeroes until both are of size N. Then, we compare the two subarrays element by element and return as soon as a point of difference is observed.
We are given multiple queries where given x we have to find the maximum element in the xth subarray sorted according to the order given above.
For example, if the array A is [3, 1, 2, 4]; then the sorted subarrays will be:
[4]
[3, 1, 2, 4]
[3, 1, 2]
[3, 1]
[3]
[2, 4]
[2]
[1, 2, 4]
[1, 2]
[1]
A query where x = 3 corresponds to finding the maximum element in the subarray [3, 1, 2]; so here the answer would be 3.
Since the number of queries are large (of the order of 10^5) and the number of elements in the array can also be large (of the order of 10^5), we would need to do some preprocessing to answer each query in O(1) or O(log N) or O(sqrt N) time. I can't seem to figure out how to do this. I have solved it for when the array contains unique elements, however how could we do this for when the array contains repetitions? Is there any data structure which could help in storing the required information?
Build suffix array in back order for this array (consider it like string)
For every entry store it's length and cumulative count (sum of lengths from the beginning of suffix array)
For query find needed index by binary search for cumulative counts, and get needed prefix of found suffix
For your examples suffixes with cumul.counts are
4 (0)
3124 (1)
34 (5)
124 (7)
query 3 finds entry 3124 (1<=3<5), and gets 3-1=2-nd (by length) prefix = 312
Does anyone know an Algorithm that sorts k-approximately an array?
We were asked to find and Algorithm for k-approximate sorting, and it should run in O(n log(n/k)). but I can't seem to find any.
K-approx. sorting means that an array and any 1 <= i <= n-k such that sum a[j] <= sum a[j] i<=j<= i+k-1 i+1<=j<= i+k
I know I'm very late to the question ... But under the assumption that k is some approximation value between 0 and 1 (when 0 is completely unsorted and 1 is perfectly sorted) surely the answer to this is quicksort (or mergesort).
Consider the following array:
[4, 6, 9, 1, 10, 8, 2, 7, 5, 3]
Let's say this array is 'unsorted' - now apply one iteration of quicksort to this array with the (length[array]/2)th element as a pivot: length[array]/2 = 5. So the 5th element is our pivot (i.e. 8):
[4, 6, 2, 1, 3, 9, 7, 10, 8]
Now this is array is not sorted - but it is more sorted than one iteration ago, i.e. its approximately sorted but for a low approximation, i.e. a low value of k. Repeat this step again on the two halves of the array and it becomes more sorted. As k increases towards 1 - i.e. perfectly sorted - the complexity becomes O(N log(N/1)) = O(N log(N)).
My teacher gave me a homework about how to Merge Sort two arrays in Pascal.
One of the arrays is named as N and sorted as ASCENDING..
Other array named as M and sorted as DESCENDING.
They are pre-defined and he wants me to Merge Sort these two arrays.
N [ 2, 4, 5, 8, 10 ]
M [ 9, 7, 6, 3, 1 ]
Merge Sort [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
So how can I do that?
Can anyone explain me this Merge Sort algorithm by simple coding examples?
Your teacher is a clever guy, actually you need to understand what a mergesort does to merge two already sorted arrays. That's how mergesort works, it splits up the problem until there are two already sorted arrays, then it merges those arrays to one sorted array. This merging will be repeated until the whole array is sorted.
That's what you need to do (the code you should write on your own...)
Create an array that is big enough to hold the elements of N and M
For each position in the target array take the smallest remaining value of N and M. The smallest one you find like this:
a. If there are no elements of N left, take the smallest element of M
b. If there are no elements of M left, take the smallest element of N
c. Otherwise compare the smallest elements of N and M and take the smaller one.
Because the arrays are already sorted, you know exactly at which position the smallest element of N and of M can be found.