The idea is to first fast forward each pointer to the end to find their distances from the end. Then we can fast forward the farther pointer so they're the same distance from the end. Finally we can fast forward both at the same time until they coincide.

This same exact approach can also be used to find the least common ancestor (LCA) of two nodes in a tree where nodes have parent pointers.

```
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
auto currA = headA, currB = headB;
int countA = 0, countB = 0;
while (currA) {
currA = currA->next, countA++;
}
while (currB) {
currB = currB->next, countB++;
}
int diff = std::abs(countA - countB);
if (countB > countA) { swap(headA, headB); }
while (diff--) {
headA = headA->next;
}
while (headA != headB) {
headA = headA->next, headB = headB->next;
}
return headA;
}
};
```