经典链表题目:相交链表

利用快慢指针浪漫求解

Posted by SWZ on November 26, 2019

题目

解题思路

快慢指针(错的人迟早会走散,而对的人迟早会相逢!浪漫解法~)

  • 创建两个指针pApB,分别初始化为链表AB的头结点。然后让它们向后逐结点遍历。

  • pA到达链表的尾部时,将它重定位到链表B的头结点 (你没看错,就是链表B); 类似的,当pB到达链表的尾部时,将它重定位到链表A的头结点。

  • 若在某一时刻pApB相遇,则pA/pB为相交结点。

  • 想弄清楚为什么这样可行, 可以考虑以下两个链表: A={1,3,5,7,9,11}B={2,4,9,11},相交于结点 9。 由于B.length (4) < A.length (6)pBpA少经过 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;
    }
};