题目分析:
. - 力扣(LeetCode)
相交链表:首先我想到的第一个思路是:如图可知,A和B链表存在长度差,从左边一起遍历链表不好找交点,那我们就从后面开始找,但是这是单链表,没有 prev 指针,所以只能反转链表 A、B。反转之后再从A、B头结点开始就可以找到相遇点,但是题目要求我们不能改变链表的结构,所以此方法不行。
方法一:
思路:
①当链表有一个为空,或者两个都为空的时候,直接返回NULL。
②因为链表存在差值,结点个数不同,不能一起遍历,所以我们可以求出A和B各自的结点个数,然后求出差值。
③差值有了之后,我们可以让长的链表先走差值步,相对于抹掉了差值。
④最后A、B链表一起走,如果地址相等就表示相遇了,就返回交点处的地址,如果没有相遇,就返回NULL
struct ListNode* getIntersectionNode(struct ListNode* headA,
struct ListNode* headB) {
struct ListNode* curA = headA;
struct ListNode* curB = headB;
if (curA == NULL || curB == NULL)
return NULL;
//求链表A、B各自的长度
int la = 0;
int lb = 0;
while (curA) {
curA = curA->next;
++la;
}
while (curB) {
curB = curB->next;
++lb;
}
//找到两个链表中较长的那个
struct ListNode* longest = headA;
struct ListNode* shortest = headB;
if (la < lb) {
longest = headB;
shortest = headA;
}
//求出差值,然后先让长的链表走完差值
int gap = abs(la - lb);
while (gap--) {
longest = longest->next;
}
//同时出发,直到相遇,否则没有相遇
while (longest) {
if (longest == shortest)
return longest;
longest = longest->next;
shortest = shortest->next;
}
return NULL;
}
方法二:
思路:
①当链表有一个为空,或者两个都为空的时候,直接返回NULL。
②相当于两个指针在一个路线上走、走的路程都是一样的
A先走完自己的路程,然后去走B的路程
B先走完自己的路程,然后去走A的路程
A和B走到路一样长
如果存在相遇点,A和B必定会相遇 (如果不是很明白可以对着代码,画图去理解一下)
如果不存在相遇点,就在NULL处相遇
struct ListNode* getIntersectionNode(struct ListNode* headA,
struct ListNode* headB) {
if (headA==NULL || headB==NULL)
{
return NULL;
}
struct ListNode* A = headA;
struct ListNode* B = headB;
while (A != B) {
A = A ? A->next : headB;
B = B ? B->next : headA;
}
return A;
}