[AcWing] 66. 两个链表的第一个公共节点

输入两个链表,找出它们的第一个公共结点。

当不存在公共节点时,返回空节点。

数据范围

链表长度 [1,2000]
保证两个链表不完全相同,即两链表的头结点不相同。

样例

1
2
3
4
5
6
7
8
给出两个链表如下所示:
A: a1 → a2

c1 → c2 → c3

B: b1 → b2 → b3

输出第一个公共节点c1

算法思想

两个链表,两种情况,相交不相交

相交

两个链表的第一个公共节点

a + c + b = b + c + a,它们相遇的时候一定是两个链表的第一个公共节点。

不相交

两个链表的第一个公共节点2

a + b = b + a,下一步它们都会走向NULL,而NULL === NULL。看作相遇。

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *findFirstCommonNode(ListNode *headA, ListNode *headB) {
ListNode * p = headA, * q = headB;

// p从headA开始走,走完从headB开始走
// q从headB开始走,走完从headA开始走

// 不管两个链表相交还是不相交. 根据 a + c + b = b + c + a 原理
// 它们一定相交
while(p != q){
// 如果p走到末尾
if(!p) p = headB;
else p = p -> next;

// 如果q走到末尾
if(!q) q = headA;
else q = q -> next;
}

return p;
}
};