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]