23. Merge K Sorted Lists
hardAsked at GleanMerge K Sorted Lists is a cornerstone Glean interview problem — it directly models merging ranked result sets from K index shards into one ordered output stream, a core operation in any distributed search engine.
By Alex Chen, Founder, InterviewChamp.AI · Last verified
Source citations
Public interview reports confirming this problem appears in Glean loops.
- Glassdoor (2026-Q1)— Frequently cited as Glean's signature hard problem — interviewers explicitly connect it to multi-shard result merging in their product.
- Blind (2025-12)— Glean SWE candidates list this as the #1 hard problem to prepare — multiple reports of it appearing in the final onsite coding round.
Problem
You are given an array of k linked-lists lists, each linked-list is sorted in ascending order. Merge all the linked-lists into one sorted linked-list and return it.
Constraints
k == lists.length0 <= k <= 10^40 <= lists[i].length <= 500−10^4 <= lists[i][j] <= 10^4lists[i] is sorted in ascending order.The sum of lists[i].length will not exceed 10^4.
Examples
Example 1
lists = [[1,4,5],[1,3,4],[2,6]][1,1,2,3,4,4,5,6]Explanation: All three sorted lists merged into one.
Example 2
lists = [][]Explanation: No lists — return null.
Approaches
1. Min-heap (priority queue)
Push the head of each non-null list into a min-heap. Repeatedly extract the minimum node, append it to the merged list, and push the next node from the same list. Repeat until the heap is empty.
- Time
- O(N log k) where N = total nodes, k = number of lists
- Space
- O(k) for the heap
// JS has no built-in heap; implement a simple MinHeap
class MinHeap {
constructor() { this.heap = []; }
push(node) {
this.heap.push(node);
this._bubbleUp(this.heap.length - 1);
}
pop() {
const top = this.heap[0];
const last = this.heap.pop();
if (this.heap.length > 0) { this.heap[0] = last; this._sinkDown(0); }
return top;
}
size() { return this.heap.length; }
_bubbleUp(i) {
while (i > 0) {
const parent = Math.floor((i - 1) / 2);
if (this.heap[parent].val <= this.heap[i].val) break;
[this.heap[parent], this.heap[i]] = [this.heap[i], this.heap[parent]];
i = parent;
}
}
_sinkDown(i) {
const n = this.heap.length;
while (true) {
let smallest = i;
const l = 2*i+1, r = 2*i+2;
if (l < n && this.heap[l].val < this.heap[smallest].val) smallest = l;
if (r < n && this.heap[r].val < this.heap[smallest].val) smallest = r;
if (smallest === i) break;
[this.heap[smallest], this.heap[i]] = [this.heap[i], this.heap[smallest]];
i = smallest;
}
}
}
function mergeKLists(lists) {
const heap = new MinHeap();
for (const head of lists) if (head) heap.push(head);
const dummy = { val: 0, next: null };
let tail = dummy;
while (heap.size() > 0) {
const node = heap.pop();
tail.next = node;
tail = tail.next;
if (node.next) heap.push(node.next);
}
return dummy.next;
}Tradeoff: O(N log k) time — optimal. The heap always has at most k elements, so log k per extraction. Requires implementing a min-heap in JavaScript — mention this overhead upfront and offer to use a sorted array as a stand-in if implementation time is tight.
2. Divide and conquer (pairwise merge)
Pair up the k lists and merge each pair. Repeat until one list remains. Uses the two-list merge subroutine recursively.
- Time
- O(N log k)
- Space
- O(log k) recursion depth
function mergeTwoLists(l1, l2) {
const dummy = { val: 0, next: null }; let tail = dummy;
while (l1 && l2) {
if (l1.val <= l2.val) { tail.next = l1; l1 = l1.next; }
else { tail.next = l2; l2 = l2.next; }
tail = tail.next;
}
tail.next = l1 || l2;
return dummy.next;
}
function mergeKLists(lists) {
if (!lists || lists.length === 0) return null;
let interval = 1;
while (interval < lists.length) {
for (let i = 0; i + interval < lists.length; i += interval * 2) {
lists[i] = mergeTwoLists(lists[i], lists[i + interval]);
}
interval *= 2;
}
return lists[0];
}Tradeoff: Same O(N log k) complexity. No heap needed — just the two-list merge. Easier to implement correctly in JavaScript. Iterative bottom-up is preferable over recursive to avoid stack depth issues.
Glean-specific tips
State the connection upfront: 'This is exactly what happens when Glean merges ranked results from multiple index shards — each shard returns a sorted list and you merge them efficiently.' Then explain why O(N log k) matters: 'Naive approach is O(Nk) — too slow for k=10,000 shards. The heap-based approach brings it to O(N log k).' Glean interviewers will probe your heap knowledge — be prepared to explain the heap operations. The divide-and-conquer approach is an excellent alternative if implementing a heap from scratch is too slow under pressure.
Common mistakes
- Using a naive O(Nk) approach (scan all k heads to find the minimum each time) — works but won't impress for a hard problem.
- Not pushing the next node after popping from the heap — the current node's successor must enter the heap.
- Forgetting to handle empty lists in the initial heap population — skip null list heads.
- In the divide-and-conquer approach, merging out of order — ensure you always merge lists[i] with lists[i + interval], not arbitrary pairs.
Follow-up questions
An interviewer at Glean may pivot to one of these next:
- What if each list is a stream (infinite, lazily generated)? How does this change the heap approach?
- Merge K Sorted Arrays — same concept but with random-access arrays instead of linked lists.
- How would you parallelize this merge across multiple machines in a distributed setting?
Solve it now
Free. No sign-up. Python and JavaScript run instantly in your browser.
FAQ
Why is the heap approach O(N log k) and not O(N log N)?
The heap contains at most k elements at any time. Each push and pop costs O(log k), and you do O(N) total push/pop operations across all N nodes. So total is O(N log k).
Which approach should I present first in a Glean interview?
The min-heap approach — it directly models the production scenario Glean cares about (streaming merge with bounded memory). Mention divide-and-conquer as an alternative that avoids implementing a heap from scratch.
Practice these live with InterviewChamp.AI
Drill Merge K Sorted Lists and other Glean interview questions under real-loop conditions with instant feedback on your reasoning, complexity claims, and code.
Practice these live with InterviewChamp.AI →