Intersection:判断两个链表是否相交,相交定义为两个指针指向同一个节点,而不是两个链表的某个后缀值是相等的。
如果两个链表的尾节点是同一块内存,则两个链表必定相交。在相交的情况下,可以从尾结点往回遍历找相交点。但不幸的是这是单链表,没法回溯,即使用递归的方法,也会因为链表不等长而无法回溯。
所以需要让两个链表等长。可以先通过一次遍历求出两个链表的长度,然后跳过较长链表前面的一些节点,最后顺序遍历找相交点。时间复杂度O(A + B)
。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
int lenA = ListLength(headA);
int lenB = ListLength(headB);
int diff = abs(lenA - lenB);
ListNode* shorter = lenA < lenB ? headA : headB;
ListNode* longer = lenA < lenB ? headB : headA;
while(diff > 0){
longer = longer->next;
diff--;
}
//书上的这种写法还是很简单的,空链表也适用
while(shorter != longer){
shorter = shorter->next;
longer = longer->next;
}
return shorter;
}
private:
int ListLength(ListNode* head)
{
int ret = 0;
while(head != nullptr){
ret++;
head = head->next;
}
return ret;
}
};