Intersection of Two Linked Lists
Problem
null if they never meet. The lists have no cycles and must be left unchanged.A=[4,1,8,4,5], B=[5,6,1,8,4,5]Outputnode 8 (tail [8,4,5] shared)A=[2,6,4] B=[1,5]Outputnull1 ≤ m, n ≤ 3·104 · 1 ≤ Node.val ≤ 105 · Follow-up: O(m+n) time, O(1) memory.
Try it yourself
class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
}
}
a walks A then B, and b
walks B then A, both travel exactly m+n steps — so they
line up on the shared tail and reach the merge node (or null) together.Instinct Nodes joined by next pointers and the task is to reverse, splice, merge, reorder or remove in place - grab a dummy head and rewire pointers carefully.
Memory hack Save next, flip, step - never let go of a rope before you've grabbed the next one.
Open the Linked List Techniques guide →Approaches
Brute ForceCompare Every Pair of Nodes
O(m·n)Space O(1)For each node of A, scan all of B looking for the
same reference. The first node of A that appears in B
is the merge point, since everything after it is shared.
public ListNode getIntersectionNode(ListNode headA, ListNode headB) { for (ListNode a = headA; a != null; a = a.next) { for (ListNode b = headB; b != null; b = b.next) { if (a == b) return a; // same object, not same value } } return null; }
No extra memory, but quadratic — ~9·108 checks at max size.
BetterHash Set of Nodes
O(m+n)Space O(n)Store every node of B (by identity) in a HashSet, then
walk A; the first node already in the set is the intersection. This
trades memory for an O(1) membership test.
public ListNode getIntersectionNode(ListNode headA, ListNode headB) { Set<ListNode> nodesInB = new HashSet<>(); for (ListNode b = headB; b != null; b = b.next) nodesInB.add(b); for (ListNode a = headA; a != null; a = a.next) { if (nodesInB.contains(a)) return a; } return null; }
Linear time, but O(n) extra memory fails the follow-up.
OptimalTwo Pointers — Switch Heads
O(m+n)Space O(1)Let the lists be A = x + c and B = y + c (c = shared
tail). When a pointer falls off its list, restart it at the other head. After
x + c + y steps both stand on the merge node; with no merge
(c = 0) both hit null after m + n steps and the
loop ends.
public ListNode getIntersectionNode(ListNode headA, ListNode headB) { if (headA == null || headB == null) return null; ListNode a = headA, b = headB; while (a != b) { a = (a == null) ? headB : a.next; b = (b == null) ? headA : b.next; } return a; // merge node, or null if none }
Linear time, O(1) memory, no length counting — answers the follow-up.
At a glance
| Level | Approach | Time | Space |
|---|---|---|---|
| Brute Force | Compare Every Pair of Nodes | O(m·n) | O(1) |
| Better | Hash Set of Nodes | O(m+n) | O(n) |
| Optimal | Two Pointers — Switch Heads | O(m+n) | O(1) |
- Comparing
a.val == b.val— equal values don't mean a shared node. - Switching to the other head on
a.next == null— skips the null step and loops forever with no merge. - Mutating the lists (e.g. marking or reversing) — the problem forbids it.
- Clarify that intersection means node identity, not value.
- Prove termination: both pointers take at most m+n+1 steps.
- Mention the length-difference variant as an equally valid O(1) answer.