CodeGround
DashboardProblemsInterviewsAssessmentsCourses
CodeGround
DashboardProblemsInterviewsAssessmentsCourses
The Technical Interview Course

0 of 170 lessons complete

  • The smallest thing, cheaply
  • Keeping only k candidates
  • Ordering by something you compute
  • Always take the most urgent thing
  • Merging many ordered sources
  • Two heaps facing each other
  • The interval problem that needed a heap
  • Retrieval: when is it a heap?

Heaps and Priority Queues

85 / 170

Heaps and Priority Queues/Lesson 5 of 8·About 68 min

Merging many ordered sources

One candidate from each source in a heap, and the answer comes out in order.

Why it works

One candidate each is enough

To merge several already-ordered sources, you never need more than one item from each in play at once. The next item overall must be the best among the current fronts, because everything behind a front is worse than that front.

So the heap holds at most one entry per source. Pop the best, emit it, and push that source's next item to replace it.

Key idea

The entry has to say where it came from

When you pop a value you need to know which source to advance, so the heap entry carries the source identifier and the position within it alongside the ordering key.

This is the derived-key idea again: key first, everything needed to continue after it. Forgetting to carry the source is the most common way this gets stuck after the first pop.

The three moving parts

A common design version of this: several users each have a list of posts in reverse chronological order, and you must produce the newest few across all of them.

Whatever the domain, the same three things have to be right. Seed the heap with one entry per source. Give each entry enough to continue with. Replace what you pop from the source it came from.

1import heapq2 3sources = [[1, 4, 5], [1, 3, 4], [2, 6]]4 5heap = [(source[0], index, 0) for index, source in enumerate(sources)]6heapq.heapify(heap)7print("one candidate per source:", sorted(heap))8 9value, which, position = heapq.heappop(heap)10print("smallest overall:", value, "came from source", which)11print("so the replacement to push is", sources[which][position + 1])
Key first, then the source, then how far along it is. Without those last two there is nothing to push next.

Tip

When the sources run the other way

These sources ascend, so the min-heap is already pointing the right way. A feed ordered newest first descends, and the fix is the negation from the first lesson: negate the key going in and negate it coming out.

Nothing else about the merge changes. Recognizing that a reversed ordering is a sign flip rather than a different algorithm saves rewriting the loop backwards.

Tip

Stopping early is most of the benefit

Producing only the first few items means the loop runs that many times rather than over everything. Combining all the sources and sorting would touch every item, which is wasted work when you want ten out of a million.

Cost is O(s) to seed the heap for s sources, then O(log s) per item produced. For a limit of L that is O(s + L log s), independent of how much data sits behind each source.

Key idea

You have solved one of these before

Merging k sorted linked lists appeared in Unit 7, where you solved it by pairing lists and merging two at a time. This heap version is the other standard solution.

Both are O(n k log k) for k lists of n nodes. Divide and conquer allocates nothing extra and processes in rounds; the heap holds k entries and produces output in a single streaming pass. That problem returns below as a review so you can build it the second way.

Complexity· 5 min

Cost of the k-way merge

Merging k sorted sources holding n items in total, using a heap with one entry per source. Give the time and the extra space beyond the output.

Python
1heap = [(source[0], index, 0) for index, source in enumerate(sources) if source]2heapq.heapify(heap)3while heap:4    value, source_index, position = heapq.heappop(heap)5    emit(value)6    if position + 1 < len(sources[source_index]):7        heapq.heappush(heap, (sources[source_index][position + 1], source_index, position + 1))
Time
Extra space
Problem· 30 min

Twitter

Read the constraints first and let them tell you what complexity is expected. Derive the approach, implement it, run the tests, and submit when it passes.

Problem· 22 min

Merge K Sorted Lists, with a heap this time

You solved this in Unit 7 by pairing lists and merging two at a time. Build it again with a heap holding one node from each list. Same complexity, completely different shape, and having both is the point.

PreviousAlways take the most urgent thing
NextTwo heaps facing each other

0 of 4 parts complete