跪拜 Guibai
← All articles
Backend · Java · Algorithm

LeetCode 21: The Easy Merge That Still Fails Half of Interview Candidates

By Rain的Java大神之路 ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

Hiring screens use a two-line problem to test pointer discipline and engineering judgment, so a miss on LeetCode 21 can cost an offer even when the candidate whiteboards DFS fluently. The split between iterative O(1) space and recursive O(m+n) stack depth maps directly to production decisions on data pipelines and long lists.

Summary

LeetCode 21 asks for merging two ascending linked lists in place, splicing the original nodes rather than copying values. The iterative solution with a dummy sentinel head is the engineering default: a `cur` tail pointer walks both lists, appending the smaller head, then grafts the remaining segment with one statement. That yields O(m+n) time and O(1) extra space and eliminates the special-case branch for the result head. The recursive version is far shorter, but each call consumes a stack frame, so depth equals merged list length; beyond roughly 100k nodes it triggers a StackOverflowError under default JVM stack sizing.

Most interview failures don't come from missing the algorithm. They come from pointer-order mistakes: writing `while (l1 != null || l2 != null)` then dereferencing null inside, forgetting to advance the tail pointer, using `<` instead of `<=` and losing stable ordering for equal values, or returning the dummy node itself so the answer grows a phantom -1. The correct sequence is fixed: attach `cur.next`, advance the selected list node, then advance `cur`, and finish by splicing the remaining non-empty list whole.

The same dummy-node pattern scales straight to the LeetCode 23 K-way merge: push the K list heads into a min-heap keyed by value, pop one, append it, and push its successor. Complexity drops from O(k·N) with sequential pairwise merging to O(N log k). Interviewers also ask about de-duplication, descending lists, and whether values may be copied into new nodes, so the follow-up set is nearly as valuable as the core implementation.

Takeaways
— The iterative merge with a dummy sentinel runs in O(m+n) time and O(1) extra space by reusing existing nodes and splicing the remaining list with one assignment.
— The recursive solution has the same O(m+n) time but O(m+n) stack depth, enough to overflow the JVM stack on list lengths around 100k.
— Pointer order matters: attach `cur.next`, advance the chosen list node, then advance `cur` last; skipping the tail advance leaves only one node in the result.
— Using `<=` rather than `<` preserves stability for equal values, a requirement for multi-field sorting and log-stream merging.
— The dummy node exists only to unify insertion logic; returning `dummy.next` is mandatory, and returning `dummy` leaks a -1 sentinel value.
— For K-way merge (LeetCode 23), a min-heap of the K list heads yields O(N log k), whereas sequential pairwise merging costs O(k·N) and times out on large inputs.
— Before coding, confirm with the interviewer whether nodes can be spliced in place; if not, copying values into new nodes degrades space to O(m+n).
Conclusions

The line between an AC solution and a senior answer is whether the candidate introduces a sentinel node without being asked and can explain why `<=` matters for stable output.

Even a 50-node toy problem gets production pressure: the recursion alternative is rejected on stack-depth grounds, showing that algorithm screens test data-scale awareness, not just correctness.

The article's progression from 21 to 88 to 23 to 148 treats one merge subroutine as the foundation for every other list-sorting technique, which generalizes: get the merge step right and the rest is scaffolding.

Concepts & terms
Sentinel node (dummy node)
A placeholder node placed before the real head of a linked list so that inserting into the head requires no special branch. In merge code, a dummy's next points at the result head; returning `dummy.next` gives the first real node and the phantom value never enters the result.
Min-heap (priority queue)
A tree-based container that always yields the smallest element in O(log n) time. For K-way merge, pushing the K list heads into a min-heap and repeatedly extracting then pushing successors produces a sorted output in O(N log k).
Source: juejin.cn ↗ Google Translate ↗ Backup ↗