简体   繁体   中英

Remove min for K sorted doubly linked lists in O(logk) time

So I'm trying to create an algorithm for the problem of removing the minimum from k sorted doubly linked lists. Here, we have k sorted doubly linked lists where n is the sum of all of the elements in all of the lists. We want to be able to remove the minimum within O(logk) time and only take O(n) time to initialize the data structure.

I was thinking of creating a minimum heap where the elements are the first element of each list (so only k elements in the heap at a time), but I'm not entirely sure where to go from there, specifically with adding the rest of the elements into the heap. Could anyone please help me out with this?

From what I understand (please correct me if I'm wrong), you have K doubly-linked lists which are sorted. You want to keep removing the smallest element. Each remove must be done in O(logK) .

Let's take an example:

A = {1, 1, 2, 3}
B = {2, 3, 4, 5}

You can insert the first element of each list along with which list it belongs to into a min-heap.

heap = [{key: 1, list: A}, {key: 2, list: B}]

Then you can pop the smallest element from the min heap. You can now delete this element.

min_val = heap.pop()     // {key: 1, list: A}
min_list = min_val.list  // list = A
min_list.delete_first()  // new A = {1, 2, 3}

After deleting, you must add the next element from this list back into the min-heap (if the list is non-empty, else skip this step).

heap.add({ 
  key: min_list.fist_element(), // key: 1
  list: min_list                // list: A
})
// new heap = [{key: 1, list: A}, {key: 2, list: B}]

Now you can repeat this for each remove operation. Pop the smallest from the min-heap O(1) , remove the smallest element (ie first element from a doubly-linked list) O(1) , add the next element from the same list back into the min-heap O(logK) .

You have k lists and all of them sum n , so each list should have an average sum of a = n/k .

The secret question is: how long do you need to iterate through a list to find out that is sums at least a ?

For example, suppose a = 10 and your list is [5, 6, 7]. Just by looking the first element (and knowing the length of the list), you know that the sum of the list is bigger than the average, so you can completely ignore it. Basically, for each element Li you read from a list L , you can ask if

L1 + L2 + ... + Li + (Li * (s - i)) >= n/k

where s is the length of the list. As long as you need to read the lists, this should cost you no aditional time and would cut around half of the lists.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM