The question goes like this-
Assuming I have an Array of real numbers X[x1,...,xn] and a natural constant k such that for every i X[i]<X[i k]. Write a sorting algorithm with time complexity better than O(nlogn). For the purpose of the question I am allowed to use quick sort, counting sort, Radix sort, bucket sort, heaps and so on.
All I've figured out so far is that if I take sublists by the remainder of the indecies (after dividing with K), those sublists are sorted. But merging them in the right complexity seems impossible. I also tried using min heaps after realizing the i smallest value must be in the first k*i places but it took me O(n^2) which is too much. I'd appreaciate any guidance/help/references. Thank you!
CodePudding user response:
Something to note here is that you essentially have m
sorted arrays that you could merge directly. That is, the sequence [x[i],x[i k],x[i 2k],x[i 3k]...]
is sorted. As is [x[i 1],x[i k 1],[x[i] 2k 1]...]
So you have to merge m
sorted sequences, where m = n/k
. The basic idea is:
- Initialize a priority queue of size k with the first item from each sorted sequence. That is, add
x[0]
,x[1]
,x[2]
,x[3]
...x[k-1]
to the priority queue. In addition, save the index of the item in the priority queue structure. - Remove the first item from the queue and add the next item from that sequence. So if the first item you remove from the queue is
x[3]
, then you'll want to addx[3 k]
to the queue. - You'll of course have to make sure that you're not attempting to add anything from beyond the end of the array.
- Continue in that fashion until the queue is empty.
Complexity is O(n log m). Basically, every item is added to and removed from a priority queue of size m. Both addition and removal are, worst case, O(log m).
CodePudding user response:
Use a min heap of size k.
Parse the array, adding to the min heap. Every time it has k elements, take the min for your sorted array. Every time it has fewer than k elements, add another to the heap.