题目
解题思路
快慢指针(错的人迟早会走散,而对的人迟早会相逢!浪漫解法~)
-
创建两个指针
pA
和pB
,分别初始化为链表A
和B
的头结点。然后让它们向后逐结点遍历。 -
当
pA
到达链表的尾部时,将它重定位到链表B
的头结点 (你没看错,就是链表B
); 类似的,当pB
到达链表的尾部时,将它重定位到链表A
的头结点。 -
若在某一时刻
pA
和pB
相遇,则pA/pB
为相交结点。 -
想弄清楚为什么这样可行, 可以考虑以下两个链表:
A={1,3,5,7,9,11}
和B={2,4,9,11}
,相交于结点9
。 由于B.length (4) < A.length (6)
,pB
比pA
少经过 2 个结点,会先到达尾部。将pB
重定向到pA
的头结点,pA
重定向到pB
的头结点后,pB
要比pA
多走2个结点。因此,它们会同时到达交点。 -
如果两个链表存在相交,它们末尾的结点必然相同。因此当
pA/pB
到达链表结尾时,记录下链表pA/pB
对应的元素。若最后元素不相同,则两个链表不相交。
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if (headA == NULL || headB == NULL) return NULL;
ListNode *headA_H = headA, *headB_H = headB;
ListNode *headA_E = NULL, *headB_E = NULL;
while (true) {
if (headA == headB) return headA;
if (headA_E != NULL && headB_E != NULL && headA_E != headB_E) return NULL;
if (headA->next != NULL)
headA = headA->next;
else {
headA_E = headA;
headA = headB_H;
}
if (headB->next != NULL)
headB = headB->next;
else {
headB_E = headB;
headB = headA_H;
}
}
return NULL;
}
};