Top-k Problems and Merging

The k biggest, without sorting everything

To find the 3 highest scores out of a million, keep a min-heap of size 3. For each new score, if it beats the smallest of your top 3 (the heap's root), swap it in:

import heapq

def top_k(nums, k):
    heap = []
    for x in nums:
        heapq.heappush(heap, x)
        if len(heap) > k:
            heapq.heappop(heap)       # throw out the smallest
    return sorted(heap, reverse=True)

print(top_k([5, 12, 3, 41, 7, 19, 2, 33], 3))

Output

[41, 33, 19]

Each step works on a heap of only k items: O(n log k), which is much faster than sorting when k is small. Python also has heapq.nlargest(k, nums) that does this for you.

Think of it like this: A talent show judge who only keeps the current top 3 photos on their desk. Every new photo is compared to the worst of the three.

Merging sorted lists

Put the first item of each list in a heap. Repeatedly take the smallest and replace it with the next item from the same list:

import heapq

def merge_lists(lists):
    heap = [(lst[0], i, 0) for i, lst in enumerate(lists) if lst]
    heapq.heapify(heap)
    out = []
    while heap:
        value, which, pos = heapq.heappop(heap)
        out.append(value)
        if pos + 1 < len(lists[which]):
            heapq.heappush(heap, (lists[which][pos + 1], which, pos + 1))
    return out

print(merge_lists([[1, 4, 9], [2, 3, 10], [5, 6]]))

Output

[1, 2, 3, 4, 5, 6, 9, 10]

Remember: Need the smallest/biggest item over and over while things keep changing? Use a heap.

HOME LABS COMMUNITY DASHBOARD