Intersection of Two Linked Lists
Two singly linked lists may join at some node and share every node from there to the end (a Y shape). Given their heads, return the first shared node — the one where they merge — or null if they never meet. Matching is by node identity (the same node object), not by value; two different nodes that happen to hold equal values do not count as an intersection. The lists must be left unchanged, and the target is O(1) extra space.
- 1 <= list lengths <= 10,000
- Intersection is by node identity, not value
- The original list structure must be preserved
- Target: O(1) extra space
listA = [4,1,8,4,5], listB = [5,6,1,8,4,5], intersect at value 8Reference to the shared node 8listA = [2,6,4], listB = [1,5], no shared nodesnullTwo lists that intersect look like a Y: each has its own private prefix, and after the junction they run down the exact same shared tail. We want that junction node. The only thing that makes it awkward is that the two private prefixes can be different lengths, so two pointers walking forward from the two heads reach the junction at different times.
Compare every node of A against every node of B — O(N × M), too slow. Or put all of A's nodes into a hash set and scan B for the first one that's already in it — O(N + M) time but O(N) extra memory. Both work; we want to keep the time and drop the memory.
Why don't two forward pointers meet on their own? Purely because one has a longer head start than the other before the junction. If we could remove that head-start difference, both pointers would be the same distance from the junction and would land on it together. One clean way: measure both lengths, advance the pointer on the longer list by the difference, then walk both in step until they point at the same node.
lenA, lenB = length(headA), length(headB)
a, b = headA, headB
for _ in range(lenA - lenB): a = a.next # skip the longer list's extra prefix
for _ in range(lenB - lenA): b = b.next
while a is not b:
a, b = a.next, b.next
return a # the junction, or None if both hit the endThere is a way to equalize the head starts without ever counting lengths. Walk pointer a through list A; when it falls off the end, send it to the head of B. Walk pointer b through list B; when it falls off the end, send it to the head of A. Now think about the total distance each travels to reach the junction. Let the private prefixes have lengths p and q, and the shared tail start at distance c from the junction on each. Pointer a travels p (its own list) then q (B's prefix) and arrives at the junction after p + q steps. Pointer b travels q then p — also p + q steps. Equal distances, so they land on the junction at the same moment. And if the lists never intersect, both pointers walk p + q steps and hit None together, ending the loop with the answer null. Either way it just works.
a, b = headA, headB
while a is not b:
a = a.next if a else headB # off the end of A → jump to B's head
b = b.next if b else headA # off the end of B → jump to A's head
return aNone once before jumping — that single None step is what keeps the two path lengths exactly equal and lets the no-intersection case terminate instead of looping forever. Comparisons are by identity (is), because we want the same node, not merely an equal value.a walks all 5 of A's nodes, hits the end, jumps to B's head. b walks all 6 of B's nodes, hits the end, jumps to A's head.a goes 5 → 6 → 1 → 8, b goes 4 → 1 → 8. Both reach node 8 after exactly 8 steps total. Return node 8.Like Merge Two Sorted Lists, this is the multiple-sequence two-pointer shape — a pointer travelling each of two lists — but the clever part is different: here we equalize the two traversal lengths so pointers over unequal paths fall into sync. That "make both walks the same length so they meet" idea is the transferable trick; recognize it whenever two linked structures share a common suffix and you must find where they join using O(1) space. The brute force screams O(N × M); the fix is to stop re-scanning and instead line the two walks up so a single synchronized pass finds the meeting point.
Phase 1: Initial Sweep
Strategy: Phase-Alignment Sweep
Both pointers pA and pB start traversing. Notice that List A is much shorter than List B.
Switching tracks ensures both pointers traverse exactly A + B nodes. This mathematical guarantee forces them to meet at the junction.
Total distance traversed is constant.
Two pointers, zero extra memory.
Neutralize depth differences.