0

I have a question at school that i need to find the kth minimum elements in a min heap. the run time that was required is o(k^2) and i understood how to do that. but if i can get it down to o(k*logk) that i get a bonus. i thought about doing a priority queue from the min heap and then inserting the node of the heap to the queue and then taking it out then doing the same thing with the children of the root of the minimum heap and so on k times. i know that the time complexity of insert and pop operations is o(logk) since The initial size of the priority queue is one, and it increases by at most one at each of the k steps. Therefore, there are maximum k+1 elements in the priority queue.

i understand what i need to do but find it complex to implement it in pseudo code any ideas or guidelines would be great.

Thank you

Anatolii
  • 14,139
  • 4
  • 35
  • 65
lanz
  • 29
  • 3

1 Answers1

0

Yes, your idea sounds good. I will show how to do this in Python.

Build heap from array

So, first build a min heap on top of your input array:

def create_min_heap(array):
    min_heap = []
    for value in array:
        heappush(min_heap, value)

    return min_heap

Count k min elements off the heap

Create a helper min-heap that will be used to retrieve all k minimum elements in O(klogk). At each step, a minimum element will be popped from it, and its 2 children nodes will be added (children can be found in the original min-heap). Please note, that it doesn't make sense to add children of other nodes to the helper min-heap because they cannot be smaller than their parents (per heap property).

def k_min_elements(min_heap, k):
    result = list()
    helper_min_heap = []
    heappush(helper_min_heap, (min_heap[0],0))
    while len(result) < k:
        min_node = heappop(helper_min_heap)
        value = min_node[0]
        index = min_node[1]

        left_index = index*2 + 1
        right_index = left_index + 1
        if left_index < len(min_heap):
            heappush(helper_min_heap, (min_heap[left_index], left_index))
        if right_index < len(min_heap):
            heappush(helper_min_heap, (min_heap[right_index], right_index))

        result.append(value)

    return result 

Full Code

Now, the full code and sample output.

from heapq import heappop
from heapq import heappush

def create_min_heap(array):
    min_heap = []
    for value in array:
        heappush(min_heap, value)

    return min_heap

def k_min_elements(min_heap, k):
    if k > len(min_heap) or k < 0:
        raise Exception("k is invalid")

    result = list()
    helper_min_heap = []
    heappush(helper_min_heap, (min_heap[0],0))
    while len(result) < k:
        min_node = heappop(helper_min_heap)
        value = min_node[0]
        index = min_node[1]

        left_index = index*2 + 1
        right_index = left_index + 1
        if left_index < len(min_heap):
            heappush(helper_min_heap, (min_heap[left_index], left_index))
        if right_index < len(min_heap):
            heappush(helper_min_heap, (min_heap[right_index], right_index))

        result.append(value)

    return result


min_heap = create_min_heap([1, 3, 5, 7, 9, 2, 4, 6, 8, 0])
print (k_min_elements(min_heap, 3))

[0, 1, 2]

Anatolii
  • 14,139
  • 4
  • 35
  • 65