The problem
You get the heads of two singly linked lists, a and b. At some node they may merge and share the same tail from then on. Return that first shared node, or None if they never meet. “Shared” means the same node object, not just an equal value.
List A: 4 -> 1 \
8 -> 4 -> 5
List B: 5 -> 6 -> 1 /
Output: the node with value 8Both lists end in the same three nodes 8 -> 4 -> 5. The first of those is the intersection. The two 1s are different nodes, so they don’t count.
How to think about it
Start with brute force. For each node in A, scan all of B looking for the same object. That is O(n·m). A better first answer: put every node of A in a set, then walk B and return the first node already in the set. That is O(n + m) time but O(n) space.
Why two simple pointers don’t work. If both lists had the same length before the merge, you could walk them in lockstep and they would arrive at the intersection together. The problem is the length difference: A has 2 nodes before the merge, B has 3, so lockstep pointers are always one node apart.
The key insight: walk A then B, and B then A. Pointer pa walks A, and when it falls off the end it jumps to B’s head. Pointer pb does the opposite. Now each pointer travels (A's private part) + (shared part) + (B's private part) before reaching the intersection a second time, in a different order. Same distance, so they arrive together. If there is no intersection, both travel lenA + lenB and reach None at the same moment, which also ends the loop.
Which pattern is this? Two pointers on linked lists. The tell is “two lists of unknown, different lengths that need to line up”.
Approach
- Set
pa = aandpb = b. - While
paandpbare not the same node:- move
paforward, or tobif it isNone; - move
pbforward, or toaif it isNone.
- move
- Return
pa. It is either the intersection node orNone.
Solution
def intersection_node(a, b):
pa, pb = a, b
while pa is not pb: # compare node identity, not value
pa = pa.next if pa else b # end of A -> jump to B
pb = pb.next if pb else a # end of B -> jump to A
return pa
# lists [4,1]->[8,4,5] and [5,6,1]->[8,4,5] share tail 8 -> node with val 8Dry run
On the example (A has 5 nodes, B has 6). Values show the node each pointer is on after the step; None is the end of a list:
| Step | pa |
pb |
Same node? |
|---|---|---|---|
| 1 | 1 (A) | 6 (B) | no |
| 4 | 5 (tail) | 4 | no |
| 5 | None |
5 (tail) | no |
| 6 | 5 (B head) | None |
no |
| 7 | 6 (B) | 4 (A head) | no |
| 8 | 1 (B) | 1 (A) | no, equal values but different nodes |
| 9 | 8 | 8 | yes |
After nine steps both pointers sit on the shared 8. On two separate lists 2 6 4 and 1 5, both pointers reach None together after six steps and the function returns None.
Complexity
- Time: O(n + m). Each pointer walks at most both lists once, plus one
Nonestep each. - Space: O(1). Two pointers.
Edge cases and pitfalls
- No intersection: the loop still terminates, because both pointers hit
Noneon the same step. That is why theNonestep is part of the walk. - One list empty: the pointer on the empty list jumps straight to the other head, and the function returns
Noneafter walking it. - Comparing values instead of nodes gives wrong answers. Step 8 above has two different nodes with value 1.
- Jumping on
pa.next is Noneinstead ofpa is Noneskips theNonestep. With no intersection the pointers then cycle forever. - Lists merge at the head (A and B are the same list):
pa is pbfrom the start and it returnsa.
Related problems
- Linked List Cycle II (LeetCode 142): another “make two pointers travel equal distances” argument.
- Remove Nth Node From End of List (LeetCode 19): two pointers with a fixed gap.
- Merge Two Sorted Lists (LeetCode 21): walking two lists side by side.
- 1.Middle of the Linked List (LeetCode 876)
- 2.Linked List Cycle (LeetCode 141)
- 3.Happy Number (LeetCode 202)
- 4.Palindrome Linked List (LeetCode 234)
- 5.Intersection of Two Linked Lists (LeetCode 160)
- 6.Linked List Cycle II (LeetCode 142)
- 7.Find the Duplicate Number (LeetCode 287)
- 8.Remove Nth Node From End of List (LeetCode 19)
- 9.Reorder List (LeetCode 143)
- 10.Circular Array Loop (LeetCode 457)