Write a program to find the node at which the intersection of two singly linked lists begins.
For example, the following two linked lists:
A: a1 → a2 ↘ c1 → c2 → c3 ↗ B: b1 → b2 → b3
begin to intersect at node c1.
Notes:
- If the two linked lists have no intersection at all, return
null
. - The linked lists must retain their original structure after the function returns.
- You may assume there are no cycles anywhere in the entire linked structure.
- Your code should preferably run in O(n) time and use only O(1) memory.
可以将A,B两个链表看做两部分,交叉前与交叉后。
交叉后的长度是一样的,因此交叉前的长度差即为总长度差diff。
只要去除这些长度差,距离交叉点就等距了。
然后先让较长的链表走diff步。然后两个链表开始同时走,若指针相等,则为交叉点的开始。
/**
* 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) {
ListNode *cpA = headA;
ListNode *cpB = headB;
int cntA = 0, cntB = 0;
while(cpA){
cntA ++;
cpA = cpA -> next;
}
while(cpB){
cntB ++;
cpB = cpB -> next;
}
cpA = headA;
cpB = headB;
bool a_is_longer = true;
if(cntA < cntB)
a_is_longer = false;
int diff = abs(cntA-cntB);
if(a_is_longer){
for(; diff > 0; diff --){
cpA = cpA -> next;
}
}
else{
for(; diff > 0; diff --){
cpB = cpB -> next;
}
}
while(cpA){
if(cpA == cpB) return cpA;
cpA = cpA -> next;
cpB = cpB -> next;
}
return cpA;
}
};