以力扣例题为例:
大思路:结点相交——同一个结点——同一个地址
思路1:
尾结点地址相同则相交:无法找到相交位置;但是使用此方法可以直接判断出不相交的情况!
思路2:
两个链表中,每个结点地址互相比较 时间复杂度为O(n^2)
思路3:
如果两个链表一样长,那么只用比较对应位置是否相等即可,时间复杂度为O(n)
注意:本题不能用逆置的思想,因为每个结点只能有一个next域
那么怎么要它们一样长呢?——采用快慢指针法
对于两个链表有长有短,那么我们通过遍历可以得到两个链表间的长度关系,让长的链表先走差距步,那么此时,两个指针指向的起始位置之后的长度即相等了
curA和curB指针分别指向这两个链表
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
struct ListNode* curA=headA;
struct ListNode* curB=headB;
//代表A、B链表的长度
int lenA=0;
int lenB=0;
//比较尾结点地址可直接排除不相交情况,因此这里寻找尾结点
while(curA->next){
lenA++;
curA=curA->next;
}
while(curB->next){
lenB++;
curB=curB->next;
}
//尾结点不相等则不相交
if(curA!=curB){
return NULL;
}
//相交:找相交位置
//长度的差距
int gap=abs(lenA-lenB);
//先假设长短,再通过if语句修正
struct ListNode* longList=headA;
struct ListNode* shortList=headB;
if(lenA<lenB){
longList=headB;
shortList=headA;
//此时就longList一定代表长链表,shortList一定代表短链表,就不用区分AB了
}
//移动差距步gap
for(int i=0;i<gap;i++){
longList=longList->next;
}
//再逐个比较是否相等,相等的位置即是相交位置起点
while(longList!=shortList){
longList=longList->next;
shortList=shortList->next;
}
return longList;
}